diff --git a/fatamorgana/basic.py b/fatamorgana/basic.py index 6194ab0..b745f2f 100644 --- a/fatamorgana/basic.py +++ b/fatamorgana/basic.py @@ -11,7 +11,8 @@ import io import warnings try: - import numpy # type: ignore + import numpy + from numpy.typing import NDArray _USE_NUMPY = True except ImportError: _USE_NUMPY = False @@ -161,7 +162,7 @@ def _py_write_bool_byte(stream: io.BufferedIOBase, bits: Tuple[Union[bool, int], InvalidDataError if didn't receive 8 bits. """ if len(bits) != 8: - raise InvalidDataError('write_bool_byte received {} bits, requires 8'.format(len(bits))) + raise InvalidDataError(f'write_bool_byte received {len(bits)} bits, requires 8') byte = 0 for i, bit in enumerate(reversed(bits)): byte |= bit << i @@ -169,7 +170,7 @@ def _py_write_bool_byte(stream: io.BufferedIOBase, bits: Tuple[Union[bool, int], if _USE_NUMPY: - def _np_read_bool_byte(stream: io.BufferedIOBase) -> List[bool]: + def _np_read_bool_byte(stream: io.BufferedIOBase) -> NDArray[numpy.uint8]: """ Read a single byte from the stream, and interpret its bits as a list of 8 booleans. @@ -198,13 +199,13 @@ if _USE_NUMPY: InvalidDataError if didn't receive 8 bits. """ if len(bits) != 8: - raise InvalidDataError('write_bool_byte received {} bits, requires 8'.format(len(bits))) + raise InvalidDataError(f'write_bool_byte received {len(bits)} bits, requires 8') return stream.write(numpy.packbits(bits)[0]) - read_bool_byte = _np_read_bool_byte + read_bool_byte = _np_read_bool_byte # type: ignore write_bool_byte = _np_write_bool_byte else: - read_bool_byte = _py_read_bool_byte + read_bool_byte = _py_read_bool_byte # type: ignore write_bool_byte = _py_write_bool_byte def read_uint(stream: io.BufferedIOBase) -> int: @@ -249,7 +250,7 @@ def write_uint(stream: io.BufferedIOBase, n: int) -> int: SignedError: if `n` is negative. """ if n < 0: - raise SignedError('uint must be positive: {}'.format(n)) + raise SignedError(f'uint must be positive: {n}') current = n byte_list = [] @@ -392,7 +393,7 @@ def write_ratio(stream: io.BufferedIOBase, r: Fraction) -> int: SignedError: if r is negative. """ if r < 0: - raise SignedError('Ratio must be unsigned: {}'.format(r)) + raise SignedError(f'Ratio must be unsigned: {r}') size = write_uint(stream, r.numerator) size += write_uint(stream, r.denominator) return size @@ -456,7 +457,7 @@ def write_float64(stream: io.BufferedIOBase, f: float) -> int: return stream.write(b) -def read_real(stream: io.BufferedIOBase, real_type: int = None) -> real_t: +def read_real(stream: io.BufferedIOBase, real_type: Optional[int] = None) -> real_t: """ Read a real number from the stream. @@ -503,13 +504,14 @@ def read_real(stream: io.BufferedIOBase, real_type: int = None) -> real_t: return read_float32(stream) if real_type == 7: return read_float64(stream) - raise InvalidDataError('Invalid real type: {}'.format(real_type)) + raise InvalidDataError(f'Invalid real type: {real_type}') -def write_real(stream: io.BufferedIOBase, - r: real_t, - force_float32: bool = False - ) -> int: +def write_real( + stream: io.BufferedIOBase, + r: real_t, + force_float32: bool = False + ) -> int: """ Write a real number to the stream. See read_real() for format details. @@ -561,7 +563,7 @@ class NString: """ _string: str - def __init__(self, string_or_bytes: Union[bytes, str]): + def __init__(self, string_or_bytes: Union[bytes, str]) -> None: """ Args: string_or_bytes: Content of the `NString`. @@ -576,9 +578,9 @@ class NString: return self._string @string.setter - def string(self, string: str): + def string(self, string: str) -> None: if len(string) == 0 or not all(0x21 <= ord(c) <= 0x7e for c in string): - raise InvalidDataError('Invalid n-string {}'.format(string)) + raise InvalidDataError(f'Invalid n-string {string}') self._string = string @property @@ -586,9 +588,9 @@ class NString: return self._string.encode('ascii') @bytes.setter - def bytes(self, bstring: bytes): + def bytes(self, bstring: bytes) -> None: if len(bstring) == 0 or not all(0x21 <= c <= 0x7e for c in bstring): - raise InvalidDataError('Invalid n-string {!r}'.format(bstring)) + raise InvalidDataError(f'Invalid n-string {bstring!r}') self._string = bstring.decode('ascii') @staticmethod @@ -675,7 +677,7 @@ class AString: """ _string: str - def __init__(self, string_or_bytes: Union[bytes, str]): + def __init__(self, string_or_bytes: Union[bytes, str]) -> None: """ Args: string_or_bytes: Content of the AString. @@ -690,9 +692,9 @@ class AString: return self._string @string.setter - def string(self, string: str): + def string(self, string: str) -> None: if not all(0x20 <= ord(c) <= 0x7e for c in string): - raise InvalidDataError('Invalid a-string {}'.format(string)) + raise InvalidDataError(f'Invalid a-string "{string}"') self._string = string @property @@ -700,9 +702,9 @@ class AString: return self._string.encode('ascii') @bytes.setter - def bytes(self, bstring: bytes): + def bytes(self, bstring: bytes) -> None: if not all(0x20 <= c <= 0x7e for c in bstring): - raise InvalidDataError('Invalid a-string {!r}'.format(bstring)) + raise InvalidDataError(f'Invalid a-string "{bstring!r}"') self._string = bstring.decode('ascii') @staticmethod @@ -786,10 +788,10 @@ class ManhattanDelta: vertical (bool): `True` if aligned along y-axis value (int): signed length of the vector """ - vertical = None # type: bool - value = None # type: int + vertical: bool + value: int - def __init__(self, x: int, y: int): + def __init__(self, x: int, y: int) -> None: """ One of `x` or `y` _must_ be zero! @@ -801,7 +803,7 @@ class ManhattanDelta: y = int(y) if x != 0: if y != 0: - raise InvalidDataError('Non-Manhattan ManhattanDelta ({}, {})'.format(x, y)) + raise InvalidDataError(f'Non-Manhattan ManhattanDelta ({x}, {y})') self.vertical = False self.value = x else: @@ -884,7 +886,7 @@ class ManhattanDelta: return hasattr(other, 'as_list') and self.as_list() == other.as_list() def __repr__(self) -> str: - return '{}'.format(self.as_list()) + return str(self.as_list()) class OctangularDelta: @@ -910,7 +912,7 @@ class OctangularDelta: proj_mag: int octangle: int - def __init__(self, x: int, y: int): + def __init__(self, x: int, y: int) -> None: """ Either `abs(x)==abs(y)`, `x==0`, or `y==0` _must_ be true! @@ -932,7 +934,7 @@ class OctangularDelta: self.proj_mag = abs(x) self.octangle = (1 << 2) | (yn << 1) | (xn != yn) else: - raise InvalidDataError('Non-octangular delta! ({}, {})'.format(x, y)) + raise InvalidDataError(f'Non-octangular delta! ({x}, {y})') def as_list(self) -> List[int]: """ @@ -1020,7 +1022,7 @@ class OctangularDelta: return hasattr(other, 'as_list') and self.as_list() == other.as_list() def __repr__(self) -> str: - return '{}'.format(self.as_list()) + return str(self.as_list()) class Delta: @@ -1034,7 +1036,7 @@ class Delta: x: int y: int - def __init__(self, x: int, y: int): + def __init__(self, x: int, y: int) -> None: """ Args: x: x-displacement @@ -1104,7 +1106,7 @@ class Delta: return hasattr(other, 'as_list') and self.as_list() == other.as_list() def __repr__(self) -> str: - return '{}'.format(self.as_list()) + return str(self.as_list()) def read_repetition(stream: io.BufferedIOBase) -> repetition_t: @@ -1128,7 +1130,7 @@ def read_repetition(stream: io.BufferedIOBase) -> repetition_t: elif rtype in (4, 5, 6, 7, 10, 11): return ArbitraryRepetition.read(stream, rtype) else: - raise InvalidDataError('Unexpected repetition type: {}'.format(rtype)) + raise InvalidDataError(f'Unexpected repetition type: {rtype}') def write_repetition(stream: io.BufferedIOBase, repetition: repetition_t) -> int: @@ -1186,11 +1188,12 @@ class GridRepetition: a_count: int b_count: Optional[int] = None - def __init__(self, - a_vector: List[int], - a_count: int, - b_vector: Optional[List[int]] = None, - b_count: Optional[int] = None): + def __init__( + self, + a_vector: Sequence[int], + a_count: int, + b_vector: Optional[Sequence[int]] = None, + b_count: Optional[int] = None): """ Args: a_vector: First lattice vector, of the form `[x, y]`. @@ -1219,10 +1222,10 @@ class GridRepetition: warnings.warn('Removed b_count and b_vector since b_count == 1') if a_count < 2: - raise InvalidDataError('Repetition has too-small a_count: ' - '{}'.format(a_count)) - self.a_vector = a_vector - self.b_vector = b_vector + raise InvalidDataError(f'Repetition has too-small a_count: {a_count}') + + self.a_vector = list(a_vector) + self.b_vector = list(b_vector) if b_vector is not None else None self.a_count = a_count self.b_count = b_count @@ -1270,8 +1273,7 @@ class GridRepetition: a_vector = Delta.read(stream).as_list() b_vector = None else: - raise InvalidDataError('Invalid type for grid repetition ' - '{}'.format(repetition_type)) + raise InvalidDataError(f'Invalid type for grid repetition {repetition_type}') return GridRepetition(a_vector, na, b_vector, nb) def write(self, stream: io.BufferedIOBase) -> int: @@ -1292,7 +1294,7 @@ class GridRepetition: """ if self.b_vector is None or self.b_count is None: if self.b_vector is not None or self.b_count is not None: - raise InvalidDataError('Malformed repetition {}'.format(self)) + raise InvalidDataError(f'Malformed repetition {self}') if self.a_vector[1] == 0: size = write_uint(stream, 2) @@ -1343,8 +1345,7 @@ class GridRepetition: return True def __repr__(self) -> str: - return 'GridRepetition: ({} : {} | {} : {})'.format(self.a_count, self.a_vector, - self.b_count, self.b_vector) + return f'GridRepetition: ({self.a_count} : {self.a_vector} | {self.b_count} : {self.b_vector})' class ArbitraryRepetition: @@ -1360,16 +1361,18 @@ class ArbitraryRepetition: x_displacements: List[int] y_displacements: List[int] - def __init__(self, - x_displacements: List[int], - y_displacements: List[int]): + def __init__( + self, + x_displacements: Sequence[int], + y_displacements: Sequence[int], + ) -> None: """ Args: x_displacements: x-displacements between consecutive elements y_displacements: y-displacements between consecutive elements """ - self.x_displacements = x_displacements - self.y_displacements = y_displacements + self.x_displacements = list(x_displacements) + self.y_displacements = list(y_displacements) @staticmethod def read(stream: io.BufferedIOBase, repetition_type: int) -> 'ArbitraryRepetition': @@ -1423,7 +1426,7 @@ class ArbitraryRepetition: x_displacements.append(x * mult) y_displacements.append(y * mult) else: - raise InvalidDataError('Invalid ArbitraryRepetition repetition_type: {}'.format(repetition_type)) + raise InvalidDataError(f'Invalid ArbitraryRepetition repetition_type: {repetition_type}') return ArbitraryRepetition(x_displacements, y_displacements) def write(self, stream: io.BufferedIOBase) -> int: @@ -1497,12 +1500,13 @@ class ArbitraryRepetition: and self.y_displacements == other.y_displacements) def __repr__(self) -> str: - return 'ArbitraryRepetition: x{} y{})'.format(self.x_displacements, self.y_displacements) + return f'ArbitraryRepetition: x{self.x_displacements} y{self.y_displacements})' -def read_point_list(stream: io.BufferedIOBase, - implicit_closed: bool, - ) -> List[List[int]]: +def read_point_list( + stream: io.BufferedIOBase, + implicit_closed: bool, + ) -> List[List[int]]: """ Read a point list from a stream. @@ -1583,16 +1587,17 @@ def read_point_list(stream: io.BufferedIOBase, if _USE_NUMPY: points = numpy.vstack((points, close_points)) else: - points.append(close_points) + points += close_points return points -def write_point_list(stream: io.BufferedIOBase, - points: List[Sequence[int]], - fast: bool = False, - implicit_closed: bool = True - ) -> int: +def write_point_list( + stream: io.BufferedIOBase, + points: List[Sequence[int]], + fast: bool = False, + implicit_closed: bool = True + ) -> int: """ Write a point list to a stream. @@ -1689,19 +1694,19 @@ def write_point_list(stream: io.BufferedIOBase, deltas = [Delta(*points[0])] + [Delta(x, y) for x, y in diff] else: previous = [0, 0] - diff = [] + diffl = [] for point in points: d = [point[0] - previous[0], point[1] - previous[1]] previous = point - diff.append(d) + diffl.append(d) - if sum(sum(p) for p in points) < sum(sum(d) for d in diff) * decision_factor: + if sum(sum(p) for p in points) < sum(sum(d) for d in diffl) * decision_factor: list_type = 4 deltas = [Delta(x, y) for x, y in points] else: list_type = 5 - deltas = [Delta(x, y) for x, y in diff] + deltas = [Delta(x, y) for x, y in diffl] size = write_uint(stream, list_type) size += write_uint(stream, len(points)) @@ -1720,7 +1725,7 @@ class PropStringReference: ref: int reference_type: Type - def __init__(self, ref: int, ref_type: Type): + def __init__(self, ref: int, ref_type: Type) -> None: """ :param ref: ID number of the target. :param ref_type: Type of the target. One of bytes, NString, AString. @@ -1732,7 +1737,7 @@ class PropStringReference: return isinstance(other, type(self)) and self.ref == other.ref and self.reference_type == other.reference_type def __repr__(self) -> str: - return '[{} : {}]'.format(self.ref_type, self.ref) + return f'[{self.ref_type} : {self.ref}]' def read_property_value(stream: io.BufferedIOBase) -> property_value_t: @@ -1789,15 +1794,16 @@ def read_property_value(stream: io.BufferedIOBase) -> property_value_t: ref = read_uint(stream) return PropStringReference(ref, ref_type) else: - raise InvalidDataError('Invalid property type: {}'.format(prop_type)) + raise InvalidDataError(f'Invalid property type: {prop_type}') -def write_property_value(stream: io.BufferedIOBase, - value: property_value_t, - force_real: bool = False, - force_signed_int: bool = False, - force_float32: bool = False - ) -> int: +def write_property_value( + stream: io.BufferedIOBase, + value: property_value_t, + force_real: bool = False, + force_signed_int: bool = False, + force_float32: bool = False, + ) -> int: """ Write a property value to a stream. @@ -1844,7 +1850,7 @@ def write_property_value(stream: io.BufferedIOBase, size = write_uint(stream, 15) size += write_uint(stream, value.ref) else: - raise Exception('Invalid property type: {} ({})'.format(type(value), value)) + raise Exception(f'Invalid property type: {type(value)} ({value})') return size @@ -1885,13 +1891,14 @@ def read_interval(stream: io.BufferedIOBase) -> Tuple[Optional[int], Optional[in elif interval_type == 4: return read_uint(stream), read_uint(stream) else: - raise InvalidDataError('Unrecognized interval type: {}'.format(interval_type)) + raise InvalidDataError(f'Unrecognized interval type: {interval_type}') -def write_interval(stream: io.BufferedIOBase, - min_bound: Optional[int] = None, - max_bound: Optional[int] = None - ) -> int: +def write_interval( + stream: io.BufferedIOBase, + min_bound: Optional[int] = None, + max_bound: Optional[int] = None, + ) -> int: """ Write an interval to a stream. Used for layer data; see `read_interval()` for format details. @@ -1942,7 +1949,7 @@ class OffsetEntry: strict: bool = False offset: int = 0 - def __init__(self, strict: bool = False, offset: int = 0): + def __init__(self, strict: bool = False, offset: int = 0) -> None: """ Args: strict: `True` if the records referenced are written in @@ -1983,7 +1990,7 @@ class OffsetEntry: return write_uint(stream, self.strict) + write_uint(stream, self.offset) def __repr__(self) -> str: - return 'Offset(s: {}, o: {})'.format(self.strict, self.offset) + return f'Offset(s: {self.strict}, o: {self.offset})' class OffsetTable: @@ -2015,13 +2022,15 @@ class OffsetTable: layernames: OffsetEntry xnames: OffsetEntry - def __init__(self, - cellnames: Optional[OffsetEntry] = None, - textstrings: Optional[OffsetEntry] = None, - propnames: Optional[OffsetEntry] = None, - propstrings: Optional[OffsetEntry] = None, - layernames: Optional[OffsetEntry] = None, - xnames: Optional[OffsetEntry] = None): + def __init__( + self, + cellnames: Optional[OffsetEntry] = None, + textstrings: Optional[OffsetEntry] = None, + propnames: Optional[OffsetEntry] = None, + propstrings: Optional[OffsetEntry] = None, + layernames: Optional[OffsetEntry] = None, + xnames: Optional[OffsetEntry] = None, + ) -> None: """ All parameters default to a non-strict entry with offset `0`. @@ -2127,7 +2136,7 @@ def write_u32(stream: io.BufferedIOBase, n: int) -> int: SignedError: if `n` is negative. """ if n < 0: - raise SignedError('Negative u32: {}'.format(n)) + raise SignedError(f'Negative u32: {n}') return stream.write(struct.pack(' None: """ Args: checksum_type: 0,1,2 (No checksum, crc32, checksum32) @@ -2207,18 +2216,16 @@ class Validation: if self.checksum_type == 0: return write_uint(stream, 0) elif self.checksum is None: - raise InvalidDataError('Checksum is empty but type is ' - '{}'.format(self.checksum_type)) + raise InvalidDataError(f'Checksum is empty but type is {self.checksum_type}') elif self.checksum_type == 1: return write_uint(stream, 1) + write_u32(stream, self.checksum) elif self.checksum_type == 2: return write_uint(stream, 2) + write_u32(stream, self.checksum) else: - raise InvalidDataError('Unrecognized checksum type: ' - '{}'.format(self.checksum_type)) + raise InvalidDataError(f'Unrecognized checksum type: {self.checksum_type}') def __repr__(self) -> str: - return 'Validation(type: {} sum: {})'.format(self.checksum_type, self.checksum) + return f'Validation(type: {self.checksum_type} sum: {self.checksum})' def write_magic_bytes(stream: io.BufferedIOBase) -> int: @@ -2247,5 +2254,4 @@ def read_magic_bytes(stream: io.BufferedIOBase): """ magic = _read(stream, len(MAGIC_BYTES)) if magic != MAGIC_BYTES: - raise InvalidDataError('Could not read magic bytes, ' - 'found {!r}'.format(magic)) + raise InvalidDataError(f'Could not read magic bytes, found {magic!r}') diff --git a/fatamorgana/main.py b/fatamorgana/main.py index b73d4c2..a11af4e 100644 --- a/fatamorgana/main.py +++ b/fatamorgana/main.py @@ -40,7 +40,7 @@ class FileModals: end_has_offset_table: bool = False started: bool = False - def __init__(self, property_target: List[records.Property]): + def __init__(self, property_target: List[records.Property]) -> None: self.property_target = property_target @@ -89,7 +89,11 @@ class OasisLayout: propstrings: Dict[int, AString] layers: List[records.LayerName] - def __init__(self, unit: real_t, validation: Validation = None): + def __init__( + self, + unit: real_t, + validation: Optional[Validation] = None, + ) -> None: """ Args: unit: Real number (i.e. int, float, or `Fraction`), grid steps per micron. @@ -132,11 +136,12 @@ class OasisLayout: pass return layout - def read_record(self, - stream: io.BufferedIOBase, - modals: Modals, - file_state: FileModals - ) -> bool: + def read_record( + self, + stream: io.BufferedIOBase, + modals: Modals, + file_state: FileModals + ) -> bool: """ Read a single record of unspecified type from a stream, adding its contents into this `OasisLayout` object. @@ -162,7 +167,7 @@ class OasisLayout: else: raise e - logger.info('read_record of type {} at position 0x{:x}'.format(record_id, stream.tell())) + logger.info(f'read_record of type {record_id} at position 0x{stream.tell():x}') record: Record @@ -182,7 +187,7 @@ class OasisLayout: # Make sure order is valid (eg, no out-of-cell geometry) if not file_state.started and record_id != 1: - raise InvalidRecordError('Non-Start record {} before Start'.format(record_id)) + raise InvalidRecordError(f'Non-Start record {record_id} before Start') if record_id == 1: if file_state.started: raise InvalidRecordError('Duplicate Start record') @@ -201,7 +206,7 @@ class OasisLayout: elif record_id in (13, 14): file_state.within_cell = True else: - raise InvalidRecordError('Unknown record id: {}'.format(record_id)) + raise InvalidRecordError(f'Unknown record id: {record_id}') if record_id == 0: ''' Pad ''' @@ -335,7 +340,7 @@ class OasisLayout: self.cells[-1].geometry.append(record) file_state.property_target = record.properties else: - raise InvalidRecordError('Unknown record id: {}'.format(record_id)) + raise InvalidRecordError(f'Unknown record id: {record_id}') return False def write(self, stream: io.BufferedIOBase) -> int: @@ -412,13 +417,14 @@ class Cell: placements: List[records.Placement] geometry: List[records.geometry_t] - def __init__(self, - name: Union[NString, str, int], - *, - properties: Optional[List[records.Property]] = None, - placements: Optional[List[records.Placement]] = None, - geometry: Optional[List[records.geometry_t]] = None, - ): + def __init__( + self, + name: Union[NString, str, int], + *, + properties: Optional[List[records.Property]] = None, + placements: Optional[List[records.Placement]] = None, + geometry: Optional[List[records.geometry_t]] = None, + ) -> None: self.name = name if isinstance(name, (NString, int)) else NString(name) self.properties = [] if properties is None else properties self.placements = [] if placements is None else placements @@ -460,9 +466,11 @@ class CellName: nstring: NString properties: List[records.Property] - def __init__(self, - nstring: Union[NString, str], - properties: Optional[List[records.Property]] = None): + def __init__( + self, + nstring: Union[NString, str], + properties: Optional[List[records.Property]] = None, + ) -> None: """ Args: nstring: The contained string. @@ -499,7 +507,7 @@ class XName: attribute: int bstring: bytes - def __init__(self, attribute: int, bstring: bytes): + def __init__(self, attribute: int, bstring: bytes) -> None: """ Args: attribute: Attribute number. diff --git a/fatamorgana/records.py b/fatamorgana/records.py index 19d50f1..453ad03 100644 --- a/fatamorgana/records.py +++ b/fatamorgana/records.py @@ -29,7 +29,7 @@ from .basic import ( ) if _USE_NUMPY: - import numpy # type: ignore + import numpy logger = logging.getLogger(__name__) @@ -76,10 +76,10 @@ class Modals: property_name: Union[int, NString, None] = None property_is_standard: Optional[bool] = None - def __init__(self): + def __init__(self) -> None: self.reset() - def reset(self): + def reset(self) -> None: """ Resets all modal variables to their default values. Default values are: @@ -133,7 +133,7 @@ class Record(metaclass=ABCMeta): Common interface for records. """ @abstractmethod - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: """ Copy all defined values from this record into the modal variables. Fill all undefined values in this record from the modal variables. @@ -144,7 +144,7 @@ class Record(metaclass=ABCMeta): pass @abstractmethod - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: """ Check all defined values in this record against those in the modal variables. If any values are equal, remove them from @@ -224,7 +224,7 @@ class Record(metaclass=ABCMeta): return copy.deepcopy(self) def __repr__(self) -> str: - return '{}: {}'.format(self.__class__, pprint.pformat(self.__dict__)) + return f'{self.__class__}: ' + pprint.pformat(self.__dict__) class GeometryMixin(metaclass=ABCMeta): @@ -255,10 +255,11 @@ class GeometryMixin(metaclass=ABCMeta): return (self.get_layer(), self.get_datatype()) -def read_refname(stream: io.BufferedIOBase, - is_present: Union[bool, int], - is_reference: Union[bool, int] - ) -> Union[None, int, NString]: +def read_refname( + stream: io.BufferedIOBase, + is_present: Union[bool, int], + is_reference: Union[bool, int] + ) -> Union[None, int, NString]: """ Helper function for reading a possibly-absent, possibly-referenced NString. @@ -279,10 +280,11 @@ def read_refname(stream: io.BufferedIOBase, return NString.read(stream) -def read_refstring(stream: io.BufferedIOBase, - is_present: Union[bool, int], - is_reference: Union[bool, int], - ) -> Union[None, int, AString]: +def read_refstring( + stream: io.BufferedIOBase, + is_present: Union[bool, int], + is_reference: Union[bool, int], + ) -> Union[None, int, AString]: """ Helper function for reading a possibly-absent, possibly-referenced `AString`. @@ -307,19 +309,18 @@ class Pad(Record): """ Pad record (ID 0) """ - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: pass - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: pass @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'Pad': if record_id != 0: - raise InvalidDataError('Invalid record id for Pad ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for Pad {record_id}') record = Pad() - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -329,31 +330,28 @@ class Pad(Record): class XYMode(Record): """ XYMode record (ID 15, 16) - - Attributes: - relative (bool): default `False` """ - relative: bool = False + relative: bool @property def absolute(self) -> bool: return not self.relative @absolute.setter - def absolute(self, b: bool): + def absolute(self, b: bool) -> None: self.relative = not b - def __init__(self, relative: bool): + def __init__(self, relative: bool) -> None: """ Args: relative: `True` if the mode is 'relative', `False` if 'absolute'. """ self.relative = relative - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: modals.xy_relative = self.relative - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: pass @staticmethod @@ -361,7 +359,7 @@ class XYMode(Record): if record_id not in (15, 16): raise InvalidDataError('Invalid record id for XYMode') record = XYMode(record_id == 16) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -373,19 +371,21 @@ class Start(Record): Start Record (ID 1) Attributes: - version (AString): "1.0" + version (AString): unit (real_t): positive real number, grid steps per micron offset_table (Optional[OffsetTable]): If `None` then table must be placed in the `End` record) """ version: AString unit: real_t - offset_table: Optional[OffsetTable] = None + offset_table: Optional[OffsetTable] - def __init__(self, - unit: real_t, - version: Union[AString, str] = None, - offset_table: Optional[OffsetTable] = None): + def __init__( + self, + unit: real_t, + version: Union[AString, str] = "1.0", + offset_table: Optional[OffsetTable] = None, + ) -> None: """ Args unit: Grid steps per micron (positive real number) @@ -394,37 +394,32 @@ class Start(Record): it in the `End` record instead. """ if unit <= 0: - raise InvalidDataError('Non-positive unit: {}'.format(unit)) + raise InvalidDataError(f'Non-positive unit: {unit}') if math.isnan(unit): raise InvalidDataError('NaN unit') if math.isinf(unit): raise InvalidDataError('Non-finite unit') self.unit = unit - if version is None: - version = AString('1.0') if isinstance(version, AString): self.version = version else: self.version = AString(version) if self.version.string != '1.0': - raise InvalidDataError('Invalid version string, ' - 'only "1.0" is allowed: ' - + str(self.version.string)) + raise InvalidDataError(f'Invalid version string, only "1.0" is allowed: "{self.version.string}"') self.offset_table = offset_table - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: modals.reset() - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: modals.reset() @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'Start': if record_id != 1: - raise InvalidDataError('Invalid record id for Start: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for Start: {record_id}') version = AString.read(stream) unit = read_real(stream) has_offset_table = read_uint(stream) == 0 @@ -434,7 +429,7 @@ class Start(Record): else: offset_table = None record = Start(unit, version, offset_table) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -458,12 +453,14 @@ class End(Record): written into the `Start` record instead validation (Validation): object containing checksum """ - offset_table: Optional[OffsetTable] = None + offset_table: Optional[OffsetTable] validation: Validation - def __init__(self, - validation: Validation, - offset_table: Optional[OffsetTable] = None): + def __init__( + self, + validation: Validation, + offset_table: Optional[OffsetTable] = None, + ) -> None: """ Args: validation: `Validation` object for this file. @@ -480,12 +477,13 @@ class End(Record): pass @staticmethod - def read(stream: io.BufferedIOBase, - record_id: int, - has_offset_table: bool - ) -> 'End': + def read( + stream: io.BufferedIOBase, + record_id: int, + has_offset_table: bool + ) -> 'End': if record_id != 2: - raise InvalidDataError('Invalid record id for End {}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for End {record_id}') if has_offset_table: offset_table: Optional[OffsetTable] = OffsetTable.read(stream) else: @@ -493,7 +491,7 @@ class End(Record): _padding_string = read_bstring(stream) # noqa validation = Validation.read(stream) record = End(validation, offset_table) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -526,10 +524,12 @@ class CBlock(Record): decompressed_byte_count: int compressed_bytes: bytes - def __init__(self, - compression_type: int, - decompressed_byte_count: int, - compressed_bytes: bytes): + def __init__( + self, + compression_type: int, + decompressed_byte_count: int, + compressed_bytes: bytes, + ) -> None: """ Args: compression_type: `0` (zlib) @@ -537,29 +537,27 @@ class CBlock(Record): compressed_bytes: The compressed data. """ if compression_type != 0: - raise InvalidDataError('CBlock: Invalid compression scheme ' - '{}'.format(compression_type)) + raise InvalidDataError(f'CBlock: Invalid compression scheme {compression_type}') self.compression_type = compression_type self.decompressed_byte_count = decompressed_byte_count self.compressed_bytes = compressed_bytes - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: pass - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: pass @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'CBlock': if record_id != 34: - raise InvalidDataError('Invalid record id for CBlock: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for CBlock: {record_id}') compression_type = read_uint(stream) decompressed_count = read_uint(stream) compressed_bytes = read_bstring(stream) record = CBlock(compression_type, decompressed_count, compressed_bytes) - logger.debug('CBlock ending at 0x{:x} was read successfully'.format(stream.tell())) + logger.debug(f'CBlock ending at 0x{stream.tell():x} was read successfully') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -570,10 +568,11 @@ class CBlock(Record): return size @staticmethod - def from_decompressed(decompressed_bytes: bytes, - compression_type: int = 0, - compression_args: Dict = None - ) -> 'CBlock': + def from_decompressed( + decompressed_bytes: bytes, + compression_type: int = 0, + compression_args: Optional[Dict[str, Any]] = None, + ) -> 'CBlock': """ Create a CBlock record from uncompressed data. @@ -597,12 +596,11 @@ class CBlock(Record): compressed_bytes = (compressor.compress(decompressed_bytes) + compressor.flush()) else: - raise InvalidDataError('Unknown compression type: ' - '{}'.format(compression_type)) + raise InvalidDataError(f'Unknown compression type: {compression_type}') return CBlock(compression_type, count, compressed_bytes) - def decompress(self, decompression_args: Dict = None) -> bytes: + def decompress(self, decompression_args: Optional[Dict[str, Any]] = None) -> bytes: """ Decompress the contents of this CBlock. @@ -625,8 +623,7 @@ class CBlock(Record): if len(decompressed_bytes) != self.decompressed_byte_count: raise InvalidDataError('Decompressed data length does not match!') else: - raise InvalidDataError('Unknown compression type: ' - '{}'.format(self.compression_type)) + raise InvalidDataError(f'Unknown compression type: {self.compression_type}') return decompressed_bytes @@ -639,11 +636,13 @@ class CellName(Record): reference_number (Optional[int]): `None` results in implicit assignment """ nstring: NString - reference_number: Optional[int] = None + reference_number: Optional[int] - def __init__(self, - nstring: Union[NString, str], - reference_number: int = None): + def __init__( + self, + nstring: Union[NString, str], + reference_number: Optional[int] = None, + ) -> None: """ Args: nstring: The contained string. @@ -656,24 +655,23 @@ class CellName(Record): self.nstring = NString(nstring) self.reference_number = reference_number - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: modals.reset() - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: modals.reset() @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'CellName': if record_id not in (3, 4): - raise InvalidDataError('Invalid record id for CellName ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for CellName {record_id}') nstring = NString.read(stream) if record_id == 4: reference_number: Optional[int] = read_uint(stream) else: reference_number = None record = CellName(nstring, reference_number) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -695,9 +693,11 @@ class PropName(Record): nstring: NString reference_number: Optional[int] = None - def __init__(self, - nstring: Union[NString, str], - reference_number: int = None): + def __init__( + self, + nstring: Union[NString, str], + reference_number: Optional[int] = None, + ) -> None: """ Args: nstring: The contained string. @@ -719,15 +719,14 @@ class PropName(Record): @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'PropName': if record_id not in (7, 8): - raise InvalidDataError('Invalid record id for PropName ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for PropName {record_id}') nstring = NString.read(stream) if record_id == 8: reference_number: Optional[int] = read_uint(stream) else: reference_number = None record = PropName(nstring, reference_number) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -750,9 +749,11 @@ class TextString(Record): astring: AString reference_number: Optional[int] = None - def __init__(self, - string: Union[AString, str], - reference_number: int = None): + def __init__( + self, + string: Union[AString, str], + reference_number: Optional[int] = None, + ) -> None: """ Args: string: The contained string. @@ -765,24 +766,23 @@ class TextString(Record): self.astring = AString(string) self.reference_number = reference_number - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: modals.reset() - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: modals.reset() @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'TextString': if record_id not in (5, 6): - raise InvalidDataError('Invalid record id for TextString: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for TextString: {record_id}') astring = AString.read(stream) if record_id == 6: reference_number: Optional[int] = read_uint(stream) else: reference_number = None record = TextString(astring, reference_number) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -803,11 +803,13 @@ class PropString(Record): reference_number (Optional[int]): `None` results in implicit assignment """ astring: AString - reference_number: Optional[int] = None + reference_number: Optional[int] - def __init__(self, - string: Union[AString, str], - reference_number: int = None): + def __init__( + self, + string: Union[AString, str], + reference_number: Optional[int] = None, + ) -> None: """ Args: string: The contained string. @@ -820,24 +822,23 @@ class PropString(Record): self.astring = AString(string) self.reference_number = reference_number - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: modals.reset() - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: modals.reset() @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'PropString': if record_id not in (9, 10): - raise InvalidDataError('Invalid record id for PropString: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for PropString: {record_id}') astring = AString.read(stream) if record_id == 10: reference_number: Optional[int] = read_uint(stream) else: reference_number = None record = PropString(astring, reference_number) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -860,15 +861,17 @@ class LayerName(Record): is_textlayer (bool): Is this a text layer? """ nstring: NString - layer_interval: Tuple - type_interval: Tuple + layer_interval: Tuple[Optional[int], Optional[int]] + type_interval: Tuple[Optional[int], Optional[int]] is_textlayer: bool - def __init__(self, - nstring: Union[NString, str], - layer_interval: Tuple, - type_interval: Tuple, - is_textlayer: bool): + def __init__( + self, + nstring: Union[NString, str], + layer_interval: Tuple[Optional[int], Optional[int]], + type_interval: Tuple[Optional[int], Optional[int]], + is_textlayer: bool, + ) -> None: """ Args: nstring: The layer name. @@ -886,23 +889,22 @@ class LayerName(Record): self.type_interval = type_interval self.is_textlayer = is_textlayer - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: modals.reset() - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: modals.reset() @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'LayerName': if record_id not in (11, 12): - raise InvalidDataError('Invalid record id for LayerName: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for LayerName: {record_id}') is_textlayer = (record_id == 12) nstring = NString.read(stream) layer_interval = read_interval(stream) type_interval = read_interval(stream) record = LayerName(nstring, layer_interval, type_interval, is_textlayer) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -924,14 +926,16 @@ class Property(Record): values (Optional[List[property_value_t]]): List of property values. is_standard (bool): Whether this is a standard property. """ - name: Optional[Union[NString, int]] = None - values: Optional[List[property_value_t]] = None - is_standard: Optional[bool] = None + name: Optional[Union[NString, int]] + values: Optional[List[property_value_t]] + is_standard: Optional[bool] - def __init__(self, - name: Union[NString, str, int, None] = None, - values: Optional[List[property_value_t]] = None, - is_standard: Optional[bool] = None): + def __init__( + self, + name: Union[NString, str, int, None] = None, + values: Optional[List[property_value_t]] = None, + is_standard: Optional[bool] = None, + ) -> None: """ Args: name: Property name, reference number, or `None` (i.e. use modal) @@ -957,12 +961,12 @@ class Property(Record): def get_is_standard(self) -> bool: return verify_modal(self.is_standard) - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: adjust_field(self, 'name', modals, 'property_name') adjust_field(self, 'values', modals, 'property_value_list') adjust_field(self, 'is_standard', modals, 'property_is_standard') - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: dedup_field(self, 'name', modals, 'property_name') dedup_field(self, 'values', modals, 'property_value_list') if self.values is None and self.name is None: @@ -971,8 +975,7 @@ class Property(Record): @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'Property': if record_id not in (28, 29): - raise InvalidDataError('Invalid record id for PropertyValue: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for PropertyValue: {record_id}') if record_id == 29: record = Property() else: @@ -997,7 +1000,7 @@ class Property(Record): # logger.warning('Malformed property record header; requested modal' # ' values but had nonzero count. Ignoring count.') record = Property(name, values, bool(s)) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -1005,8 +1008,7 @@ class Property(Record): return write_uint(stream, 29) else: if self.is_standard is None: - raise InvalidDataError('Property has value or name, ' - 'but no is_standard flag!') + raise InvalidDataError('Property has value or name, but no is_standard flag!') if self.values is not None: value_count = len(self.values) v = 0 @@ -1047,12 +1049,14 @@ class XName(Record): """ attribute: int bstring: bytes - reference_number: Optional[int] = None + reference_number: Optional[int] - def __init__(self, - attribute: int, - bstring: bytes, - reference_number: int = None): + def __init__( + self, + attribute: int, + bstring: bytes, + reference_number: Optional[int] = None, + ) -> None: """ Args: attribute: Attribute number. @@ -1064,17 +1068,16 @@ class XName(Record): self.bstring = bstring self.reference_number = reference_number - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: modals.reset() - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: modals.reset() @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'XName': if record_id not in (30, 31): - raise InvalidDataError('Invalid record id for XName: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for XName: {record_id}') attribute = read_uint(stream) bstring = read_bstring(stream) if record_id == 31: @@ -1082,7 +1085,7 @@ class XName(Record): else: reference_number = None record = XName(attribute, bstring, reference_number) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -1107,10 +1110,12 @@ class XElement(Record): bstring: bytes properties: List['Property'] - def __init__(self, - attribute: int, - bstring: bytes, - properties: Optional[List['Property']] = None): + def __init__( + self, + attribute: int, + bstring: bytes, + properties: Optional[List['Property']] = None, + ) -> None: """ Args: attribute: Attribute number. @@ -1121,21 +1126,20 @@ class XElement(Record): self.bstring = bstring self.properties = [] if properties is None else properties - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: pass - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: pass @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'XElement': if record_id != 32: - raise InvalidDataError('Invalid record id for XElement: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for XElement: {record_id}') attribute = read_uint(stream) bstring = read_bstring(stream) record = XElement(attribute, bstring) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -1168,15 +1172,17 @@ class XGeometry(Record, GeometryMixin): repetition: Optional[repetition_t] = None properties: List['Property'] - def __init__(self, - attribute: int, - bstring: bytes, - layer: Optional[int] = None, - datatype: Optional[int] = None, - x: Optional[int] = None, - y: Optional[int] = None, - repetition: Optional[repetition_t] = None, - properties: Optional[List['Property']] = None): + def __init__( + self, + attribute: int, + bstring: bytes, + layer: Optional[int] = None, + datatype: Optional[int] = None, + x: Optional[int] = None, + y: Optional[int] = None, + repetition: Optional[repetition_t] = None, + properties: Optional[List['Property']] = None, + ) -> None: """ Args: attribute: Attribute number for this XGeometry. @@ -1197,13 +1203,13 @@ class XGeometry(Record, GeometryMixin): self.repetition = repetition self.properties = [] if properties is None else properties - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: adjust_coordinates(self, modals, 'geometry_x', 'geometry_y') adjust_repetition(self, modals) adjust_field(self, 'layer', modals, 'layer') adjust_field(self, 'datatype', modals, 'datatype') - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: dedup_coordinates(self, modals, 'geometry_x', 'geometry_y') dedup_repetition(self, modals) dedup_field(self, 'layer', modals, 'layer') @@ -1212,8 +1218,7 @@ class XGeometry(Record, GeometryMixin): @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'XGeometry': if record_id != 33: - raise InvalidDataError('Invalid record id for XGeometry: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for XGeometry: {record_id}') z0, z1, z2, x, y, r, d, l = read_bool_byte(stream) if z0 or z1 or z2: @@ -1233,7 +1238,7 @@ class XGeometry(Record, GeometryMixin): optional['repetition'] = read_repetition(stream) record = XGeometry(attribute, bstring, **optional) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -1269,17 +1274,17 @@ class Cell(Record): """ name: Union[int, NString] - def __init__(self, name: Union[int, str, NString]): + def __init__(self, name: Union[int, str, NString]) -> None: """ Args: name: `NString`, or an int specifying a `CellName` reference number. """ self.name = name if isinstance(name, (int, NString)) else NString(name) - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: modals.reset() - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: modals.reset() @staticmethod @@ -1290,10 +1295,9 @@ class Cell(Record): elif record_id == 14: name = NString.read(stream) else: - raise InvalidDataError('Invalid record id for Cell: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for Cell: {record_id}') record = Cell(name) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -1331,15 +1335,17 @@ class Placement(Record): flip: bool properties: List['Property'] - def __init__(self, - flip: bool, - name: Union[NString, str, int, None] = None, - magnification: Optional[real_t] = None, - angle: Optional[real_t] = None, - x: Optional[int] = None, - y: Optional[int] = None, - repetition: Optional[repetition_t] = None, - properties: Optional[List['Property']] = None): + def __init__( + self, + flip: bool, + name: Union[NString, str, int, None] = None, + magnification: Optional[real_t] = None, + angle: Optional[real_t] = None, + x: Optional[int] = None, + y: Optional[int] = None, + repetition: Optional[repetition_t] = None, + properties: Optional[List['Property']] = None, + ) -> None: """ Args: flip: Whether to perform reflection about the x-axis. @@ -1374,12 +1380,12 @@ class Placement(Record): def get_y(self) -> int: return verify_modal(self.y) - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: adjust_coordinates(self, modals, 'placement_x', 'placement_y') adjust_repetition(self, modals) adjust_field(self, 'name', modals, 'placement_cell') - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: dedup_coordinates(self, modals, 'placement_x', 'placement_y') dedup_repetition(self, modals) dedup_field(self, 'name', modals, 'placement_cell') @@ -1387,8 +1393,7 @@ class Placement(Record): @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'Placement': if record_id not in (17, 18): - raise InvalidDataError('Invalid record id for Placement: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for Placement: {record_id}') #CNXYRAAF (17) or CNXYRMAF (18) c, n, x, y, r, ma0, ma1, flip = read_bool_byte(stream) @@ -1413,7 +1418,7 @@ class Placement(Record): optional['repetition'] = read_repetition(stream) record = Placement(flip, name, **optional) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -1479,14 +1484,16 @@ class Text(Record, GeometryMixin): repetition: Optional[repetition_t] = None properties: List['Property'] - def __init__(self, - string: Union[AString, str, int, None] = None, - layer: Optional[int] = None, - datatype: Optional[int] = None, - x: Optional[int] = None, - y: Optional[int] = None, - repetition: Optional[repetition_t] = None, - properties: Optional[List['Property']] = None): + def __init__( + self, + string: Union[AString, str, int, None] = None, + layer: Optional[int] = None, + datatype: Optional[int] = None, + x: Optional[int] = None, + y: Optional[int] = None, + repetition: Optional[repetition_t] = None, + properties: Optional[List['Property']] = None, + ) -> None: """ Args: string: Text content, or `TextString` reference number. @@ -1512,14 +1519,14 @@ class Text(Record, GeometryMixin): def get_string(self) -> Union[AString, int]: return verify_modal(self.string) # type: ignore - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: adjust_coordinates(self, modals, 'text_x', 'text_y') adjust_repetition(self, modals) adjust_field(self, 'string', modals, 'text_string') adjust_field(self, 'layer', modals, 'text_layer') adjust_field(self, 'datatype', modals, 'text_datatype') - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: dedup_coordinates(self, modals, 'text_x', 'text_y') dedup_repetition(self, modals) dedup_field(self, 'string', modals, 'text_string') @@ -1529,8 +1536,7 @@ class Text(Record, GeometryMixin): @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'Text': if record_id != 19: - raise InvalidDataError('Invalid record id for Text: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for Text: {record_id}') z0, c, n, x, y, r, d, l = read_bool_byte(stream) if z0: @@ -1550,7 +1556,7 @@ class Text(Record, GeometryMixin): optional['repetition'] = read_repetition(stream) record = Text(string, **optional) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -1613,16 +1619,18 @@ class Rectangle(Record, GeometryMixin): is_square: bool = False properties: List['Property'] - def __init__(self, - is_square: bool = False, - layer: Optional[int] = None, - datatype: Optional[int] = None, - width: Optional[int] = None, - height: Optional[int] = None, - x: Optional[int] = None, - y: Optional[int] = None, - repetition: Optional[repetition_t] = None, - properties: Optional[List['Property']] = None): + def __init__( + self, + is_square: bool = False, + layer: Optional[int] = None, + datatype: Optional[int] = None, + width: Optional[int] = None, + height: Optional[int] = None, + x: Optional[int] = None, + y: Optional[int] = None, + repetition: Optional[repetition_t] = None, + properties: Optional[List['Property']] = None, + ) -> None: self.is_square = is_square self.layer = layer self.datatype = datatype @@ -1643,7 +1651,7 @@ class Rectangle(Record, GeometryMixin): return verify_modal(self.width) return verify_modal(self.height) - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: adjust_coordinates(self, modals, 'geometry_x', 'geometry_y') adjust_repetition(self, modals) adjust_field(self, 'layer', modals, 'layer') @@ -1654,7 +1662,7 @@ class Rectangle(Record, GeometryMixin): else: adjust_field(self, 'height', modals, 'geometry_h') - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: dedup_coordinates(self, modals, 'geometry_x', 'geometry_y') dedup_repetition(self, modals) dedup_field(self, 'layer', modals, 'layer') @@ -1668,8 +1676,7 @@ class Rectangle(Record, GeometryMixin): @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'Rectangle': if record_id != 20: - raise InvalidDataError('Invalid record id for Rectangle: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for Rectangle: {record_id}') is_square, w, h, x, y, r, d, l = read_bool_byte(stream) optional: Dict[str, Any] = {} @@ -1688,7 +1695,7 @@ class Rectangle(Record, GeometryMixin): if r: optional['repetition'] = read_repetition(stream) record = Rectangle(is_square, **optional) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -1750,14 +1757,16 @@ class Polygon(Record, GeometryMixin): point_list: Optional[point_list_t] = None properties: List['Property'] - def __init__(self, - point_list: Optional[point_list_t] = None, - layer: Optional[int] = None, - datatype: Optional[int] = None, - x: Optional[int] = None, - y: Optional[int] = None, - repetition: Optional[repetition_t] = None, - properties: Optional[List['Property']] = None): + def __init__( + self, + point_list: Optional[point_list_t] = None, + layer: Optional[int] = None, + datatype: Optional[int] = None, + x: Optional[int] = None, + y: Optional[int] = None, + repetition: Optional[repetition_t] = None, + properties: Optional[List['Property']] = None, + ) -> None: self.layer = layer self.datatype = datatype self.x = x @@ -1773,14 +1782,14 @@ class Polygon(Record, GeometryMixin): def get_point_list(self) -> point_list_t: return verify_modal(self.point_list) - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: adjust_coordinates(self, modals, 'geometry_x', 'geometry_y') adjust_repetition(self, modals) adjust_field(self, 'layer', modals, 'layer') adjust_field(self, 'datatype', modals, 'datatype') adjust_field(self, 'point_list', modals, 'polygon_point_list') - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: dedup_coordinates(self, modals, 'geometry_x', 'geometry_y') dedup_repetition(self, modals) dedup_field(self, 'layer', modals, 'layer') @@ -1790,8 +1799,7 @@ class Polygon(Record, GeometryMixin): @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'Polygon': if record_id != 21: - raise InvalidDataError('Invalid record id for Polygon: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for Polygon: {record_id}') z0, z1, p, x, y, r, d, l = read_bool_byte(stream) if z0 or z1: @@ -1811,7 +1819,7 @@ class Polygon(Record, GeometryMixin): if r: optional['repetition'] = read_repetition(stream) record = Polygon(**optional) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug('Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase, fast: bool = False) -> int: @@ -1876,17 +1884,19 @@ class Path(Record, GeometryMixin): extension_end: Optional[pathextension_t] = None properties: List['Property'] - def __init__(self, - point_list: Optional[point_list_t] = None, - half_width: Optional[int] = None, - extension_start: Optional[pathextension_t] = None, - extension_end: Optional[pathextension_t] = None, - layer: Optional[int] = None, - datatype: Optional[int] = None, - x: Optional[int] = None, - y: Optional[int] = None, - repetition: Optional[repetition_t] = None, - properties: Optional[List['Property']] = None): + def __init__( + self, + point_list: Optional[point_list_t] = None, + half_width: Optional[int] = None, + extension_start: Optional[pathextension_t] = None, + extension_end: Optional[pathextension_t] = None, + layer: Optional[int] = None, + datatype: Optional[int] = None, + x: Optional[int] = None, + y: Optional[int] = None, + repetition: Optional[repetition_t] = None, + properties: Optional[List['Property']] = None, + ) -> None: self.layer = layer self.datatype = datatype self.x = x @@ -1910,7 +1920,7 @@ class Path(Record, GeometryMixin): def get_extension_end(self) -> pathextension_t: return verify_modal(self.extension_end) - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: adjust_coordinates(self, modals, 'geometry_x', 'geometry_y') adjust_repetition(self, modals) adjust_field(self, 'layer', modals, 'layer') @@ -1920,7 +1930,7 @@ class Path(Record, GeometryMixin): adjust_field(self, 'extension_start', modals, 'path_extension_start') adjust_field(self, 'extension_end', modals, 'path_extension_end') - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: dedup_coordinates(self, modals, 'geometry_x', 'geometry_y') dedup_repetition(self, modals) dedup_field(self, 'layer', modals, 'layer') @@ -1933,8 +1943,7 @@ class Path(Record, GeometryMixin): @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'Path': if record_id != 22: - raise InvalidDataError('Invalid record id for Path: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for Path: {record_id}') e, w, p, x, y, r, d, l = read_bool_byte(stream) optional: Dict[str, Any] = {} @@ -1959,7 +1968,7 @@ class Path(Record, GeometryMixin): elif ext_scheme == 3: return PathExtensionScheme.Arbitrary, read_sint(stream) else: - raise InvalidDataError('Invalid ext_scheme: {}'.format(ext_scheme)) + raise InvalidDataError(f'Invalid ext_scheme: {ext_scheme}') optional['extension_start'] = get_pathext(scheme_start) optional['extension_end'] = get_pathext(scheme_end) @@ -1972,7 +1981,7 @@ class Path(Record, GeometryMixin): if r: optional['repetition'] = read_repetition(stream) record = Path(**optional) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase, fast: bool = False) -> int: @@ -2058,18 +2067,20 @@ class Trapezoid(Record, GeometryMixin): is_vertical: bool properties: List['Property'] - def __init__(self, - is_vertical: bool, - delta_a: int = 0, - delta_b: int = 0, - layer: int = None, - datatype: int = None, - width: int = None, - height: int = None, - x: int = None, - y: int = None, - repetition: repetition_t = None, - properties: Optional[List['Property']] = None): + def __init__( + self, + is_vertical: bool, + delta_a: int = 0, + delta_b: int = 0, + layer: Optional[int] = None, + datatype: Optional[int] = None, + width: Optional[int] = None, + height: Optional[int] = None, + x: Optional[int] = None, + y: Optional[int] = None, + repetition: Optional[repetition_t] = None, + properties: Optional[List['Property']] = None, + ) -> None: """ Raises: InvalidDataError: if dimensions are impossible. @@ -2088,12 +2099,10 @@ class Trapezoid(Record, GeometryMixin): if self.is_vertical: if height is not None and delta_b - delta_a > height: - raise InvalidDataError('Trapezoid: h < delta_b - delta_a' - + ' ({} < {} - {})'.format(height, delta_b, delta_a)) + raise InvalidDataError(f'Trapezoid: h < delta_b - delta_a ({height} < {delta_b} - {delta_a})') else: if width is not None and delta_b - delta_a > width: - raise InvalidDataError('Trapezoid: w < delta_b - delta_a' - + ' ({} < {} - {})'.format(width, delta_b, delta_a)) + raise InvalidDataError(f'Trapezoid: w < delta_b - delta_a ({width} < {delta_b} - {delta_a})') def get_is_vertical(self) -> bool: return verify_modal(self.is_vertical) @@ -2110,7 +2119,7 @@ class Trapezoid(Record, GeometryMixin): def get_height(self) -> int: return verify_modal(self.height) - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: adjust_coordinates(self, modals, 'geometry_x', 'geometry_y') adjust_repetition(self, modals) adjust_field(self, 'layer', modals, 'layer') @@ -2118,7 +2127,7 @@ class Trapezoid(Record, GeometryMixin): adjust_field(self, 'width', modals, 'geometry_w') adjust_field(self, 'height', modals, 'geometry_h') - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: dedup_coordinates(self, modals, 'geometry_x', 'geometry_y') dedup_repetition(self, modals) dedup_field(self, 'layer', modals, 'layer') @@ -2129,8 +2138,7 @@ class Trapezoid(Record, GeometryMixin): @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'Trapezoid': if record_id not in (23, 24, 25): - raise InvalidDataError('Invalid record id for Trapezoid: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for Trapezoid: {record_id}') is_vertical, w, h, x, y, r, d, l = read_bool_byte(stream) optional: Dict[str, Any] = {} @@ -2153,7 +2161,7 @@ class Trapezoid(Record, GeometryMixin): if r: optional['repetition'] = read_repetition(stream) record = Trapezoid(bool(is_vertical), **optional) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -2260,16 +2268,18 @@ class CTrapezoid(Record, GeometryMixin): repetition: Optional[repetition_t] = None properties: List['Property'] - def __init__(self, - ctrapezoid_type: int = None, - layer: int = None, - datatype: int = None, - width: int = None, - height: int = None, - x: int = None, - y: int = None, - repetition: repetition_t = None, - properties: Optional[List['Property']] = None): + def __init__( + self, + ctrapezoid_type: Optional[int] = None, + layer: Optional[int] = None, + datatype: Optional[int] = None, + width: Optional[int] = None, + height: Optional[int] = None, + x: Optional[int] = None, + y: Optional[int] = None, + repetition: Optional[repetition_t] = None, + properties: Optional[List['Property']] = None, + ) -> None: """ Raises: InvalidDataError: if dimensions are invalid. @@ -2303,7 +2313,7 @@ class CTrapezoid(Record, GeometryMixin): return verify_modal(self.height) return verify_modal(self.width) - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: adjust_coordinates(self, modals, 'geometry_x', 'geometry_y') adjust_repetition(self, modals) adjust_field(self, 'layer', modals, 'layer') @@ -2312,21 +2322,19 @@ class CTrapezoid(Record, GeometryMixin): if self.ctrapezoid_type in (20, 21): if self.width is not None: - raise InvalidDataError('CTrapezoid has spurious width entry: ' - '{}'.format(self.width)) + raise InvalidDataError(f'CTrapezoid has spurious width entry: {self.width}') else: adjust_field(self, 'width', modals, 'geometry_w') if self.ctrapezoid_type in (16, 17, 18, 19, 22, 23, 25): if self.height is not None: - raise InvalidDataError('CTrapezoid has spurious height entry: ' - '{}'.format(self.height)) + raise InvalidDataError(f'CTrapezoid has spurious height entry: {self.height}') else: adjust_field(self, 'height', modals, 'geometry_h') self.check_valid() - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: dedup_coordinates(self, modals, 'geometry_x', 'geometry_y') dedup_repetition(self, modals) dedup_field(self, 'layer', modals, 'layer') @@ -2337,15 +2345,13 @@ class CTrapezoid(Record, GeometryMixin): if self.ctrapezoid_type in (20, 21): if self.width is not None: - raise InvalidDataError('CTrapezoid has spurious width entry: ' - '{}'.format(self.width)) + raise InvalidDataError(f'CTrapezoid has spurious width entry: {self.width}') else: dedup_field(self, 'width', modals, 'geometry_w') if self.ctrapezoid_type in (16, 17, 18, 19, 22, 23, 25): if self.height is not None: - raise InvalidDataError('CTrapezoid has spurious height entry: ' - '{}'.format(self.height)) + raise InvalidDataError(f'CTrapezoid has spurious height entry: {self.height}') else: dedup_field(self, 'height', modals, 'geometry_h') @@ -2354,8 +2360,7 @@ class CTrapezoid(Record, GeometryMixin): @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'CTrapezoid': if record_id != 26: - raise InvalidDataError('Invalid record id for CTrapezoid: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for CTrapezoid: {record_id}') t, w, h, x, y, r, d, l = read_bool_byte(stream) optional: Dict[str, Any] = {} @@ -2376,7 +2381,7 @@ class CTrapezoid(Record, GeometryMixin): if r: optional['repetition'] = read_repetition(stream) record = CTrapezoid(**optional) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -2409,35 +2414,28 @@ class CTrapezoid(Record, GeometryMixin): size += self.repetition.write(stream) # type: ignore return size - def check_valid(self): + def check_valid(self) -> None: ctrapezoid_type = self.ctrapezoid_type width = self.width height = self.height if ctrapezoid_type in (20, 21) and width is not None: - raise InvalidDataError('CTrapezoid has spurious width entry: ' - '{}'.format(width)) + raise InvalidDataError(f'CTrapezoid has spurious width entry: {width}') if ctrapezoid_type in (16, 17, 18, 19, 22, 23, 25) and height is not None: - raise InvalidDataError('CTrapezoid has spurious height entry: ' - '{}'.format(height)) + raise InvalidDataError(f'CTrapezoid has spurious height entry: {height}') if width is not None and height is not None: if ctrapezoid_type in range(0, 4) and width < height: - raise InvalidDataError('CTrapezoid has width < height' - ' ({} < {})'.format(width, height)) + raise InvalidDataError(f'CTrapezoid has width < height ({width} < {height})') if ctrapezoid_type in range(4, 8) and width < 2 * height: - raise InvalidDataError('CTrapezoid has width < 2*height' - ' ({} < 2 * {})'.format(width, height)) + raise InvalidDataError(f'CTrapezoid has width < 2*height ({width} < 2 * {height})') if ctrapezoid_type in range(8, 12) and width > height: - raise InvalidDataError('CTrapezoid has width > height' - ' ({} > {})'.format(width, height)) + raise InvalidDataError(f'CTrapezoid has width > height ({width} > {height})') if ctrapezoid_type in range(12, 16) and 2 * width > height: - raise InvalidDataError('CTrapezoid has 2*width > height' - ' ({} > 2 * {})'.format(width, height)) + raise InvalidDataError(f'CTrapezoid has 2*width > height ({width} > 2 * {height})') if ctrapezoid_type is not None and ctrapezoid_type not in range(0, 26): - raise InvalidDataError('CTrapezoid has invalid type: ' - '{}'.format(ctrapezoid_type)) + raise InvalidDataError(f'CTrapezoid has invalid type: {ctrapezoid_type}') class Circle(Record, GeometryMixin): @@ -2453,22 +2451,24 @@ class Circle(Record, GeometryMixin): repetition (Optional[repetition_t]): Repetition, if any properties (List[Property]): List of property records associate with this record. """ - layer: Optional[int] = None - datatype: Optional[int] = None - x: Optional[int] = None - y: Optional[int] = None - repetition: Optional[repetition_t] = None - radius: Optional[int] = None + layer: Optional[int] + datatype: Optional[int] + x: Optional[int] + y: Optional[int] + repetition: Optional[repetition_t] + radius: Optional[int] properties: List['Property'] - def __init__(self, - radius: int = None, - layer: int = None, - datatype: int = None, - x: int = None, - y: int = None, - repetition: repetition_t = None, - properties: Optional[List['Property']] = None): + def __init__( + self, + radius: Optional[int] = None, + layer: Optional[int] = None, + datatype: Optional[int] = None, + x: Optional[int] = None, + y: Optional[int] = None, + repetition: Optional[repetition_t] = None, + properties: Optional[List['Property']] = None, + ) -> None: """ Args: radius: Radius. Default `None` (reuse modal). @@ -2493,14 +2493,14 @@ class Circle(Record, GeometryMixin): def get_radius(self) -> int: return verify_modal(self.radius) - def merge_with_modals(self, modals: Modals): + def merge_with_modals(self, modals: Modals) -> None: adjust_coordinates(self, modals, 'geometry_x', 'geometry_y') adjust_repetition(self, modals) adjust_field(self, 'layer', modals, 'layer') adjust_field(self, 'datatype', modals, 'datatype') adjust_field(self, 'radius', modals, 'circle_radius') - def deduplicate_with_modals(self, modals: Modals): + def deduplicate_with_modals(self, modals: Modals) -> None: dedup_coordinates(self, modals, 'geometry_x', 'geometry_y') dedup_repetition(self, modals) dedup_field(self, 'layer', modals, 'layer') @@ -2510,8 +2510,7 @@ class Circle(Record, GeometryMixin): @staticmethod def read(stream: io.BufferedIOBase, record_id: int) -> 'Circle': if record_id != 27: - raise InvalidDataError('Invalid record id for Circle: ' - '{}'.format(record_id)) + raise InvalidDataError(f'Invalid record id for Circle: {record_id}') z0, z1, has_radius, x, y, r, d, l = read_bool_byte(stream) if z0 or z1: @@ -2531,7 +2530,7 @@ class Circle(Record, GeometryMixin): if r: optional['repetition'] = read_repetition(stream) record = Circle(**optional) - logger.debug('Record ending at 0x{:x}:\n {}'.format(stream.tell(), record)) + logger.debug(f'Record ending at 0x{stream.tell():x}:\n {record}') return record def write(self, stream: io.BufferedIOBase) -> int: @@ -2559,7 +2558,7 @@ class Circle(Record, GeometryMixin): return size -def adjust_repetition(record, modals: Modals): +def adjust_repetition(record, modals: Modals) -> None: """ Merge the record's repetition entry with the one in the modals @@ -2581,7 +2580,7 @@ def adjust_repetition(record, modals: Modals): modals.repetition = copy.copy(record.repetition) -def adjust_field(record, r_field: str, modals: Modals, m_field: str): +def adjust_field(record, r_field: str, modals: Modals, m_field: str) -> None: """ Merge `record.r_field` with `modals.m_field` @@ -2602,10 +2601,10 @@ def adjust_field(record, r_field: str, modals: Modals, m_field: str): if m is not None: setattr(record, r_field, copy.copy(m)) else: - raise InvalidDataError('Unfillable field: {}'.format(m_field)) + raise InvalidDataError(f'Unfillable field: {m_field}') -def adjust_coordinates(record, modals: Modals, mx_field: str, my_field: str): +def adjust_coordinates(record, modals: Modals, mx_field: str, my_field: str) -> None: """ Merge `record.x` and `record.y` with `modals.mx_field` and `modals.my_field`, taking into account the value of `modals.xy_relative`. @@ -2639,7 +2638,7 @@ def adjust_coordinates(record, modals: Modals, mx_field: str, my_field: str): # TODO: Clarify the docs on the dedup_* functions -def dedup_repetition(record, modals: Modals): +def dedup_repetition(record, modals: Modals) -> None: """ Deduplicate the record's repetition entry with the one in the modals. Update the one in the modals if they are different. @@ -2666,7 +2665,7 @@ def dedup_repetition(record, modals: Modals): modals.repetition = record.repetition -def dedup_field(record, r_field: str, modals: Modals, m_field: str): +def dedup_field(record, r_field: str, modals: Modals, m_field: str) -> None: """ Deduplicate `record.r_field` using `modals.m_field` Update the `modals.m_field` if they are different. @@ -2699,7 +2698,7 @@ def dedup_field(record, r_field: str, modals: Modals, m_field: str): raise InvalidDataError('Unfillable field') -def dedup_coordinates(record, modals: Modals, mx_field: str, my_field: str): +def dedup_coordinates(record, modals: Modals, mx_field: str, my_field: str) -> None: """ Deduplicate `record.x` and `record.y` using `modals.mx_field` and `modals.my_field`, taking into account the value of `modals.xy_relative`. diff --git a/fatamorgana/test/build_testfiles.py b/fatamorgana/test/build_testfiles.py index 0dedfc4..e776c61 100644 --- a/fatamorgana/test/build_testfiles.py +++ b/fatamorgana/test/build_testfiles.py @@ -12,7 +12,8 @@ from . import ( test_files_circles, test_files_ctrapezoids, test_files_trapezoids, test_files_placements, test_files_paths, test_files_modals, test_files_polygons, test_files_rectangles, test_files_empty, - test_files_texts, test_files_cells) + test_files_texts, test_files_cells, + ) def build_file(num: str, func: Callable[[BufferedIOBase], BufferedIOBase]) -> None: