forked from jan/fatamorgana
		
	Modernize type annotations
This commit is contained in:
		
							parent
							
								
									d61bbc530f
								
							
						
					
					
						commit
						a4c1e52ff8
					
				@ -3,6 +3,8 @@
 | 
				
			|||||||
**fatamorgana** is a Python package for reading and writing OASIS format layout files.
 | 
					**fatamorgana** is a Python package for reading and writing OASIS format layout files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Homepage:** https://mpxd.net/code/jan/fatamorgana
 | 
					**Homepage:** https://mpxd.net/code/jan/fatamorgana
 | 
				
			||||||
 | 
					* [PyPI](https://pypi.org/project/fatamorgana)
 | 
				
			||||||
 | 
					* [Github mirror](https://github.com/anewusername/fatamorgana)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Capabilities:**
 | 
					**Capabilities:**
 | 
				
			||||||
* This package is a work-in-progress and is largely untested -- it works for
 | 
					* This package is a work-in-progress and is largely untested -- it works for
 | 
				
			||||||
@ -20,7 +22,7 @@
 | 
				
			|||||||
## Installation
 | 
					## Installation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Dependencies:**
 | 
					**Dependencies:**
 | 
				
			||||||
* python 3.5 or newer
 | 
					* python >=3.10
 | 
				
			||||||
* (optional) numpy
 | 
					* (optional) numpy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@
 | 
				
			|||||||
This module contains all datatypes and parsing/writing functions for
 | 
					This module contains all datatypes and parsing/writing functions for
 | 
				
			||||||
 all abstractions below the 'record' or 'block' level.
 | 
					 all abstractions below the 'record' or 'block' level.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
from typing import List, Tuple, Type, Union, Optional, Any, Sequence, IO
 | 
					from typing import Type, Union, Any, Sequence, IO
 | 
				
			||||||
from fractions import Fraction
 | 
					from fractions import Fraction
 | 
				
			||||||
from enum import Enum
 | 
					from enum import Enum
 | 
				
			||||||
import math
 | 
					import math
 | 
				
			||||||
@ -132,7 +132,7 @@ def write_byte(stream: IO[bytes], n: int) -> int:
 | 
				
			|||||||
    return stream.write(bytes((n,)))
 | 
					    return stream.write(bytes((n,)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _py_read_bool_byte(stream: IO[bytes]) -> List[bool]:
 | 
					def _py_read_bool_byte(stream: IO[bytes]) -> list[bool]:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Read a single byte from the stream, and interpret its bits as
 | 
					    Read a single byte from the stream, and interpret its bits as
 | 
				
			||||||
      a list of 8 booleans.
 | 
					      a list of 8 booleans.
 | 
				
			||||||
@ -147,7 +147,7 @@ def _py_read_bool_byte(stream: IO[bytes]) -> List[bool]:
 | 
				
			|||||||
    bits = [bool((byte >> i) & 0x01) for i in reversed(range(8))]
 | 
					    bits = [bool((byte >> i) & 0x01) for i in reversed(range(8))]
 | 
				
			||||||
    return bits
 | 
					    return bits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _py_write_bool_byte(stream: IO[bytes], bits: Tuple[Union[bool, int], ...]) -> int:
 | 
					def _py_write_bool_byte(stream: IO[bytes], bits: tuple[bool | int, ...]) -> int:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Pack 8 booleans into a byte, and write it to the stream.
 | 
					    Pack 8 booleans into a byte, and write it to the stream.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -184,7 +184,7 @@ if _USE_NUMPY:
 | 
				
			|||||||
        byte_arr = _read(stream, 1)
 | 
					        byte_arr = _read(stream, 1)
 | 
				
			||||||
        return numpy.unpackbits(numpy.frombuffer(byte_arr, dtype=numpy.uint8))
 | 
					        return numpy.unpackbits(numpy.frombuffer(byte_arr, dtype=numpy.uint8))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _np_write_bool_byte(stream: IO[bytes], bits: Tuple[Union[bool, int], ...]) -> int:
 | 
					    def _np_write_bool_byte(stream: IO[bytes], bits: tuple[Union[bool, int], ...]) -> int:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Pack 8 booleans into a byte, and write it to the stream.
 | 
					        Pack 8 booleans into a byte, and write it to the stream.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -457,7 +457,7 @@ def write_float64(stream: IO[bytes], f: float) -> int:
 | 
				
			|||||||
    return stream.write(b)
 | 
					    return stream.write(b)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def read_real(stream: IO[bytes], real_type: Optional[int] = None) -> real_t:
 | 
					def read_real(stream: IO[bytes], real_type: int | None = None) -> real_t:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Read a real number from the stream.
 | 
					    Read a real number from the stream.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -783,13 +783,12 @@ def write_astring(stream: IO[bytes], string: str) -> int:
 | 
				
			|||||||
class ManhattanDelta:
 | 
					class ManhattanDelta:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Class representing an axis-aligned ("Manhattan") vector.
 | 
					    Class representing an axis-aligned ("Manhattan") vector.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    Attributes:
 | 
					 | 
				
			||||||
        vertical (bool): `True` if aligned along y-axis
 | 
					 | 
				
			||||||
        value (int): signed length of the vector
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    vertical: bool
 | 
					    vertical: bool
 | 
				
			||||||
 | 
					    """`True` if aligned along y-axis"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    value: int
 | 
					    value: int
 | 
				
			||||||
 | 
					    """signed length of the vector"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, x: int, y: int) -> None:
 | 
					    def __init__(self, x: int, y: int) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@ -810,7 +809,7 @@ class ManhattanDelta:
 | 
				
			|||||||
            self.vertical = True
 | 
					            self.vertical = True
 | 
				
			||||||
            self.value = y
 | 
					            self.value = y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def as_list(self) -> List[int]:
 | 
					    def as_list(self) -> list[int]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Return a list representation of this vector.
 | 
					        Return a list representation of this vector.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -892,10 +891,13 @@ class ManhattanDelta:
 | 
				
			|||||||
class OctangularDelta:
 | 
					class OctangularDelta:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Class representing an axis-aligned or 45-degree ("Octangular") vector.
 | 
					    Class representing an axis-aligned or 45-degree ("Octangular") vector.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    proj_mag: int
 | 
				
			||||||
 | 
					    """projection of the vector onto the x or y axis (non-zero)"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Attributes:
 | 
					    octangle: int
 | 
				
			||||||
        proj_mag (int): projection of the vector onto the x or y axis (non-zero)
 | 
					    """
 | 
				
			||||||
        octangle (int): bitfield:
 | 
					    bitfield:
 | 
				
			||||||
        bit 2: 1 if non-axis-aligned (non-Manhattan)
 | 
					        bit 2: 1 if non-axis-aligned (non-Manhattan)
 | 
				
			||||||
        if Manhattan:
 | 
					        if Manhattan:
 | 
				
			||||||
            bit 1: 1 if direction is negative
 | 
					            bit 1: 1 if direction is negative
 | 
				
			||||||
@ -909,8 +911,6 @@ class OctangularDelta:
 | 
				
			|||||||
            4: +x+y, 5: -x+y,
 | 
					            4: +x+y, 5: -x+y,
 | 
				
			||||||
            6: +x-y, 7: -x-y
 | 
					            6: +x-y, 7: -x-y
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    proj_mag: int
 | 
					 | 
				
			||||||
    octangle: int
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, x: int, y: int) -> None:
 | 
					    def __init__(self, x: int, y: int) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@ -936,7 +936,7 @@ class OctangularDelta:
 | 
				
			|||||||
        else:
 | 
					        else:
 | 
				
			||||||
            raise InvalidDataError(f'Non-octangular delta! ({x}, {y})')
 | 
					            raise InvalidDataError(f'Non-octangular delta! ({x}, {y})')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def as_list(self) -> List[int]:
 | 
					    def as_list(self) -> list[int]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Return a list representation of this vector.
 | 
					        Return a list representation of this vector.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1028,13 +1028,12 @@ class OctangularDelta:
 | 
				
			|||||||
class Delta:
 | 
					class Delta:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Class representing an arbitrary vector
 | 
					    Class representing an arbitrary vector
 | 
				
			||||||
 | 
					 | 
				
			||||||
    Attributes
 | 
					 | 
				
			||||||
        x (int): x-displacement
 | 
					 | 
				
			||||||
        y (int): y-displacement
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    x: int
 | 
					    x: int
 | 
				
			||||||
 | 
					    """x-displacement"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    y: int
 | 
					    y: int
 | 
				
			||||||
 | 
					    """y-displacement"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, x: int, y: int) -> None:
 | 
					    def __init__(self, x: int, y: int) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@ -1047,7 +1046,7 @@ class Delta:
 | 
				
			|||||||
        self.x = x
 | 
					        self.x = x
 | 
				
			||||||
        self.y = y
 | 
					        self.y = y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def as_list(self) -> List[int]:
 | 
					    def as_list(self) -> list[int]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Return a list representation of this vector.
 | 
					        Return a list representation of this vector.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1168,32 +1167,35 @@ class ReuseRepetition:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class GridRepetition:
 | 
					class GridRepetition:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Class representing a repetition entry denoting a 1D or 2D array
 | 
					    A repetition entry denoting a 1D or 2D array of regularly-spaced elements. The
 | 
				
			||||||
     of regularly-spaced elements. The spacings are stored as one or
 | 
					    spacings are stored as one or two lattice vectors, and the extent of the grid
 | 
				
			||||||
     two lattice vectors, and the extent of the grid is stored as the
 | 
					    is stored as the number of elements along each lattice vector.
 | 
				
			||||||
     number of elements along each lattice vector.
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Attributes:
 | 
					    a_vector: list[int]
 | 
				
			||||||
        a_vector (Tuple[int, int]): `(xa, ya)` vector specifying a center-to-center
 | 
					    """`(xa, ya)` vector specifying a center-to-center
 | 
				
			||||||
    displacement between adjacent elements in the grid.
 | 
					    displacement between adjacent elements in the grid.
 | 
				
			||||||
        b_vector (Optional[Tuple[int, int]]): `(xb, yb)`, a second displacement,
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    b_vector: list[int] | None = None
 | 
				
			||||||
 | 
					    """`(xb, yb)`, a second displacement,
 | 
				
			||||||
    present if a 2D grid is being specified.
 | 
					    present if a 2D grid is being specified.
 | 
				
			||||||
        a_count (int): number of elements (>=1) along the grid axis specified by
 | 
					    """
 | 
				
			||||||
                        `a_vector`.
 | 
					
 | 
				
			||||||
        b_count (Optional[int]): Number of elements (>=1) along the grid axis
 | 
					    a_count: int
 | 
				
			||||||
 | 
					    """number of elements (>=1) along the grid axis specified by `a_vector`."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    b_count: int | None = None
 | 
				
			||||||
 | 
					    """Number of elements (>=1) along the grid axis
 | 
				
			||||||
    specified by `b_vector`, if `b_vector` is not `None`.
 | 
					    specified by `b_vector`, if `b_vector` is not `None`.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    a_vector: List[int]
 | 
					 | 
				
			||||||
    b_vector: Optional[List[int]] = None
 | 
					 | 
				
			||||||
    a_count: int
 | 
					 | 
				
			||||||
    b_count: Optional[int] = None
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
            self,
 | 
					            self,
 | 
				
			||||||
            a_vector: Sequence[int],
 | 
					            a_vector: Sequence[int],
 | 
				
			||||||
            a_count: int,
 | 
					            a_count: int,
 | 
				
			||||||
            b_vector: Optional[Sequence[int]] = None,
 | 
					            b_vector: Sequence[int] | None = None,
 | 
				
			||||||
            b_count: Optional[int] = None):
 | 
					            b_count: int | None = None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
            a_vector: First lattice vector, of the form `[x, y]`.
 | 
					            a_vector: First lattice vector, of the form `[x, y]`.
 | 
				
			||||||
@ -1245,8 +1247,8 @@ class GridRepetition:
 | 
				
			|||||||
        Raises:
 | 
					        Raises:
 | 
				
			||||||
            InvalidDataError: if `repetition_type` is invalid.
 | 
					            InvalidDataError: if `repetition_type` is invalid.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        nb: Optional[int]
 | 
					        nb: int | None
 | 
				
			||||||
        b_vector: Optional[List[int]]
 | 
					        b_vector: list[int] | None
 | 
				
			||||||
        if repetition_type == 1:
 | 
					        if repetition_type == 1:
 | 
				
			||||||
            na = read_uint(stream) + 2
 | 
					            na = read_uint(stream) + 2
 | 
				
			||||||
            nb = read_uint(stream) + 2
 | 
					            nb = read_uint(stream) + 2
 | 
				
			||||||
@ -1352,14 +1354,13 @@ class ArbitraryRepetition:
 | 
				
			|||||||
    """
 | 
					    """
 | 
				
			||||||
    Class representing a repetition entry denoting a 1D or 2D array
 | 
					    Class representing a repetition entry denoting a 1D or 2D array
 | 
				
			||||||
     of arbitrarily-spaced elements.
 | 
					     of arbitrarily-spaced elements.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    Attributes:
 | 
					 | 
				
			||||||
        x_displacements (List[int]): x-displacements between consecutive elements
 | 
					 | 
				
			||||||
        y_displacements (List[int]): y-displacements between consecutive elements
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    x_displacements: List[int]
 | 
					    x_displacements: list[int]
 | 
				
			||||||
    y_displacements: List[int]
 | 
					    """x-displacements between consecutive elements"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    y_displacements: list[int]
 | 
				
			||||||
 | 
					    """y-displacements between consecutive elements"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
            self,
 | 
					            self,
 | 
				
			||||||
@ -1443,7 +1444,7 @@ class ArbitraryRepetition:
 | 
				
			|||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            Number of bytes written.
 | 
					            Number of bytes written.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        def get_gcd(vals: List[int]) -> int:
 | 
					        def get_gcd(vals: list[int]) -> int:
 | 
				
			||||||
            """
 | 
					            """
 | 
				
			||||||
            Get the greatest common denominator of a list of ints.
 | 
					            Get the greatest common denominator of a list of ints.
 | 
				
			||||||
            """
 | 
					            """
 | 
				
			||||||
@ -1506,7 +1507,7 @@ class ArbitraryRepetition:
 | 
				
			|||||||
def read_point_list(
 | 
					def read_point_list(
 | 
				
			||||||
        stream: IO[bytes],
 | 
					        stream: IO[bytes],
 | 
				
			||||||
        implicit_closed: bool,
 | 
					        implicit_closed: bool,
 | 
				
			||||||
        ) -> List[List[int]]:
 | 
					        ) -> Sequence[Sequence[int]]:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Read a point list from a stream.
 | 
					    Read a point list from a stream.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1594,7 +1595,7 @@ def read_point_list(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
def write_point_list(
 | 
					def write_point_list(
 | 
				
			||||||
        stream: IO[bytes],
 | 
					        stream: IO[bytes],
 | 
				
			||||||
        points: List[Sequence[int]],
 | 
					        points: list[Sequence[int]],
 | 
				
			||||||
        fast: bool = False,
 | 
					        fast: bool = False,
 | 
				
			||||||
        implicit_closed: bool = True
 | 
					        implicit_closed: bool = True
 | 
				
			||||||
        ) -> int:
 | 
					        ) -> int:
 | 
				
			||||||
@ -1655,7 +1656,7 @@ def write_point_list(
 | 
				
			|||||||
        return size
 | 
					        return size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Try writing a bunch of Manhattan or Octangular deltas
 | 
					    # Try writing a bunch of Manhattan or Octangular deltas
 | 
				
			||||||
    deltas: Union[List[ManhattanDelta], List[OctangularDelta], List[Delta]]
 | 
					    deltas: list[ManhattanDelta] | list[OctangularDelta] | list[Delta]
 | 
				
			||||||
    list_type = None
 | 
					    list_type = None
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        deltas = [ManhattanDelta(x, y) for x, y in points]
 | 
					        deltas = [ManhattanDelta(x, y) for x, y in points]
 | 
				
			||||||
@ -1717,13 +1718,12 @@ def write_point_list(
 | 
				
			|||||||
class PropStringReference:
 | 
					class PropStringReference:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Reference to a property string.
 | 
					    Reference to a property string.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    Attributes:
 | 
					 | 
				
			||||||
        ref (int): ID of the target
 | 
					 | 
				
			||||||
        ref_type (Type): Type of the target: `bytes`, `NString`, or `AString`
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    ref: int
 | 
					    ref: int
 | 
				
			||||||
 | 
					    """ID of the target"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reference_type: Type
 | 
					    reference_type: Type
 | 
				
			||||||
 | 
					    """Type of the target: `bytes`, `NString`, or `AString`"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, ref: int, ref_type: Type) -> None:
 | 
					    def __init__(self, ref: int, ref_type: Type) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@ -1854,7 +1854,7 @@ def write_property_value(
 | 
				
			|||||||
    return size
 | 
					    return size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def read_interval(stream: IO[bytes]) -> Tuple[Optional[int], Optional[int]]:
 | 
					def read_interval(stream: IO[bytes]) -> tuple[int | None, int | None]:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Read an interval from a stream.
 | 
					    Read an interval from a stream.
 | 
				
			||||||
    These are used for storing layer info.
 | 
					    These are used for storing layer info.
 | 
				
			||||||
@ -1896,8 +1896,8 @@ def read_interval(stream: IO[bytes]) -> Tuple[Optional[int], Optional[int]]:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
def write_interval(
 | 
					def write_interval(
 | 
				
			||||||
        stream: IO[bytes],
 | 
					        stream: IO[bytes],
 | 
				
			||||||
        min_bound: Optional[int] = None,
 | 
					        min_bound: int | None = None,
 | 
				
			||||||
        max_bound: Optional[int] = None,
 | 
					        max_bound: int | None = None,
 | 
				
			||||||
        ) -> int:
 | 
					        ) -> int:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Write an interval to a stream.
 | 
					    Write an interval to a stream.
 | 
				
			||||||
@ -1931,23 +1931,24 @@ def write_interval(
 | 
				
			|||||||
class OffsetEntry:
 | 
					class OffsetEntry:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Entry for the file's offset table.
 | 
					    Entry for the file's offset table.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    Attributes:
 | 
					 | 
				
			||||||
        strict (bool): If `False`, the records pointed to by this
 | 
					 | 
				
			||||||
            offset entry may also appear elsewhere in the file. If `True`, all
 | 
					 | 
				
			||||||
            records of the type pointed to by this offset entry must be present
 | 
					 | 
				
			||||||
            in a contiuous block at the specified offset [pad records also allowed].
 | 
					 | 
				
			||||||
            Additionally:
 | 
					 | 
				
			||||||
            - All references to strict-mode records must be
 | 
					 | 
				
			||||||
                explicit (using reference_number).
 | 
					 | 
				
			||||||
            - The offset may point to an encapsulating CBlock record, if the first
 | 
					 | 
				
			||||||
                record in that CBlock is of the target record type. A strict modei
 | 
					 | 
				
			||||||
                table cannot begin in the middle of a CBlock.
 | 
					 | 
				
			||||||
        offset (int): offset from the start of the file; may be 0
 | 
					 | 
				
			||||||
                for records that are not present.
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    strict: bool = False
 | 
					    strict: bool = False
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    If `False`, the records pointed to by this offset entry may also appear
 | 
				
			||||||
 | 
					    elsewhere in the file. If `True`, all records of the type pointed to by
 | 
				
			||||||
 | 
					    this offset entry must be present in a contiuous block at the specified
 | 
				
			||||||
 | 
					    offset [pad records also allowed].
 | 
				
			||||||
 | 
					    Additionally:
 | 
				
			||||||
 | 
					        - All references to strict-mode records must be explicit (using
 | 
				
			||||||
 | 
					          `reference_number`).
 | 
				
			||||||
 | 
					        - The offset may point to an encapsulating CBlock record, if the first
 | 
				
			||||||
 | 
					          record in that CBlock is of the target record type. A strict mode
 | 
				
			||||||
 | 
					          table cannot begin in the middle of a CBlock.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    offset: int = 0
 | 
					    offset: int = 0
 | 
				
			||||||
 | 
					    """offset from the start of the file; 0 for records that are not present."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, strict: bool = False, offset: int = 0) -> None:
 | 
					    def __init__(self, strict: bool = False, offset: int = 0) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@ -2006,14 +2007,6 @@ class OffsetTable:
 | 
				
			|||||||
    XName
 | 
					    XName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    which are stored in the above order in the file's offset table.
 | 
					    which are stored in the above order in the file's offset table.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    Attributes:
 | 
					 | 
				
			||||||
        cellnames (OffsetEntry): Offset for CellNames
 | 
					 | 
				
			||||||
        textstrings (OffsetEntry): Offset for TextStrings
 | 
					 | 
				
			||||||
        propnames (OffsetEntry): Offset for PropNames
 | 
					 | 
				
			||||||
        propstrings (OffsetEntry): Offset for PropStrings
 | 
					 | 
				
			||||||
        layernames (OffsetEntry): Offset for LayerNames
 | 
					 | 
				
			||||||
        xnames (OffsetEntry): Offset for XNames
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    cellnames:   OffsetEntry
 | 
					    cellnames:   OffsetEntry
 | 
				
			||||||
    textstrings: OffsetEntry
 | 
					    textstrings: OffsetEntry
 | 
				
			||||||
@ -2024,12 +2017,12 @@ class OffsetTable:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
            self,
 | 
					            self,
 | 
				
			||||||
            cellnames: Optional[OffsetEntry] = None,
 | 
					            cellnames: OffsetEntry | None = None,
 | 
				
			||||||
            textstrings: Optional[OffsetEntry] = None,
 | 
					            textstrings: OffsetEntry | None = None,
 | 
				
			||||||
            propnames: Optional[OffsetEntry] = None,
 | 
					            propnames: OffsetEntry | None = None,
 | 
				
			||||||
            propstrings: Optional[OffsetEntry] = None,
 | 
					            propstrings: OffsetEntry | None = None,
 | 
				
			||||||
            layernames: Optional[OffsetEntry] = None,
 | 
					            layernames: OffsetEntry | None = None,
 | 
				
			||||||
            xnames: Optional[OffsetEntry] = None,
 | 
					            xnames: OffsetEntry | None = None,
 | 
				
			||||||
            ) -> None:
 | 
					            ) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        All parameters default to a non-strict entry with offset `0`.
 | 
					        All parameters default to a non-strict entry with offset `0`.
 | 
				
			||||||
@ -2149,14 +2142,18 @@ class Validation:
 | 
				
			|||||||
    The checksum is calculated using the entire file, excluding the final 4 bytes
 | 
					    The checksum is calculated using the entire file, excluding the final 4 bytes
 | 
				
			||||||
      (the value of the checksum itself).
 | 
					      (the value of the checksum itself).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Attributes:
 | 
					 | 
				
			||||||
        checksum_type (int): `0` for no checksum, `1` for crc32, `2` for checksum32
 | 
					 | 
				
			||||||
        checksum (Optional[int]): value of the checksum
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    checksum_type: int
 | 
					    checksum_type: int
 | 
				
			||||||
    checksum: Optional[int] = None
 | 
					    """
 | 
				
			||||||
 | 
					    `0` for no checksum,
 | 
				
			||||||
 | 
					    `1` for crc32,
 | 
				
			||||||
 | 
					    `2` for checksum32,
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, checksum_type: int, checksum: Optional[int] = None) -> None:
 | 
					    checksum: int | None = None
 | 
				
			||||||
 | 
					    """value of the checksum"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, checksum_type: int, checksum: int | None = None) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
            checksum_type: 0,1,2 (No checksum, crc32, checksum32)
 | 
					            checksum_type: 0,1,2 (No checksum, crc32, checksum32)
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@ This module contains data structures and functions for reading from and
 | 
				
			|||||||
 writing to whole OASIS layout files, and provides a few additional
 | 
					 writing to whole OASIS layout files, and provides a few additional
 | 
				
			||||||
 abstractions for the data contained inside them.
 | 
					 abstractions for the data contained inside them.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
from typing import List, Dict, Union, Optional, Type, IO
 | 
					from typing import Type, IO
 | 
				
			||||||
import io
 | 
					import io
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,20 +27,20 @@ class FileModals:
 | 
				
			|||||||
    """
 | 
					    """
 | 
				
			||||||
    File-scoped modal variables
 | 
					    File-scoped modal variables
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    cellname_implicit: Optional[bool] = None
 | 
					    cellname_implicit: bool | None = None
 | 
				
			||||||
    propname_implicit: Optional[bool] = None
 | 
					    propname_implicit: bool | None = None
 | 
				
			||||||
    xname_implicit: Optional[bool] = None
 | 
					    xname_implicit: bool | None = None
 | 
				
			||||||
    textstring_implicit: Optional[bool] = None
 | 
					    textstring_implicit: bool | None = None
 | 
				
			||||||
    propstring_implicit: Optional[bool] = None
 | 
					    propstring_implicit: bool | None = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    property_target: List[records.Property]
 | 
					    property_target: list[records.Property]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    within_cell: bool = False
 | 
					    within_cell: bool = False
 | 
				
			||||||
    within_cblock: bool = False
 | 
					    within_cblock: bool = False
 | 
				
			||||||
    end_has_offset_table: bool = False
 | 
					    end_has_offset_table: bool = False
 | 
				
			||||||
    started: bool = False
 | 
					    started: bool = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, property_target: List[records.Property]) -> None:
 | 
					    def __init__(self, property_target: list[records.Property]) -> None:
 | 
				
			||||||
        self.property_target = property_target
 | 
					        self.property_target = property_target
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -53,46 +53,48 @@ class OasisLayout:
 | 
				
			|||||||
        record objects.
 | 
					        record objects.
 | 
				
			||||||
    Cells are stored using `Cell` objects (different from `records.Cell`
 | 
					    Cells are stored using `Cell` objects (different from `records.Cell`
 | 
				
			||||||
        record objects).
 | 
					        record objects).
 | 
				
			||||||
 | 
					 | 
				
			||||||
    Attributes:
 | 
					 | 
				
			||||||
        (File properties)
 | 
					 | 
				
			||||||
        version (AString): Version string ('1.0')
 | 
					 | 
				
			||||||
        unit (real_t): grid steps per micron
 | 
					 | 
				
			||||||
        validation (Validation): checksum data
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        (Names)
 | 
					 | 
				
			||||||
        cellnames (Dict[int, CellName]): Cell names
 | 
					 | 
				
			||||||
        propnames (Dict[int, NString]): Property names
 | 
					 | 
				
			||||||
        xnames (Dict[int, XName]): Custom names
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        (Strings)
 | 
					 | 
				
			||||||
        textstrings (Dict[int, AString]): Text strings
 | 
					 | 
				
			||||||
        propstrings (Dict[int, AString]): Property strings
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        (Data)
 | 
					 | 
				
			||||||
        layers (List[records.LayerName]): Layer definitions
 | 
					 | 
				
			||||||
        properties (List[records.Property]): Property values
 | 
					 | 
				
			||||||
        cells (List[Cell]): Layout cells
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					    # File properties
 | 
				
			||||||
    version: AString
 | 
					    version: AString
 | 
				
			||||||
 | 
					    """File format version string ('1.0')"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unit: real_t
 | 
					    unit: real_t
 | 
				
			||||||
 | 
					    """grid steps per micron"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    validation: Validation
 | 
					    validation: Validation
 | 
				
			||||||
 | 
					    """checksum data"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    properties: List[records.Property]
 | 
					    # Data
 | 
				
			||||||
    cells: List['Cell']
 | 
					    properties: list[records.Property]
 | 
				
			||||||
 | 
					    """Property values"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cellnames: Dict[int, 'CellName']
 | 
					    cells: list['Cell']
 | 
				
			||||||
    propnames: Dict[int, NString]
 | 
					    """Layout cells"""
 | 
				
			||||||
    xnames: Dict[int, 'XName']
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    textstrings: Dict[int, AString]
 | 
					    layers: list[records.LayerName]
 | 
				
			||||||
    propstrings: Dict[int, AString]
 | 
					    """Layer definitions"""
 | 
				
			||||||
    layers: List[records.LayerName]
 | 
					
 | 
				
			||||||
 | 
					    # Names
 | 
				
			||||||
 | 
					    cellnames: dict[int, 'CellName']
 | 
				
			||||||
 | 
					    """Cell names"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    propnames: dict[int, NString]
 | 
				
			||||||
 | 
					    """Property names"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xnames: dict[int, 'XName']
 | 
				
			||||||
 | 
					    """Custom names"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # String storage
 | 
				
			||||||
 | 
					    textstrings: dict[int, AString]
 | 
				
			||||||
 | 
					    """Text strings"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    propstrings: dict[int, AString]
 | 
				
			||||||
 | 
					    """Property strings"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
            self,
 | 
					            self,
 | 
				
			||||||
            unit: real_t,
 | 
					            unit: real_t,
 | 
				
			||||||
            validation: Optional[Validation] = None,
 | 
					            validation: Validation | None = None,
 | 
				
			||||||
            ) -> None:
 | 
					            ) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
@ -404,26 +406,21 @@ class OasisLayout:
 | 
				
			|||||||
class Cell:
 | 
					class Cell:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Representation of an OASIS cell.
 | 
					    Representation of an OASIS cell.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    Attributes:
 | 
					 | 
				
			||||||
        name (Union[NString, int]): name or "CellName reference" number
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        properties (List[records.Property]): Properties of this cell
 | 
					 | 
				
			||||||
        placements (List[records.Placement]): Placement record objects
 | 
					 | 
				
			||||||
        geometry: (List[records.geometry_t]): Geometry record objectes
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    name: Union[NString, int]
 | 
					    name: NString | int
 | 
				
			||||||
    properties: List[records.Property]
 | 
					    """name or "CellName reference" number"""
 | 
				
			||||||
    placements: List[records.Placement]
 | 
					
 | 
				
			||||||
    geometry: List[records.geometry_t]
 | 
					    properties: list[records.Property]
 | 
				
			||||||
 | 
					    placements: list[records.Placement]
 | 
				
			||||||
 | 
					    geometry: list[records.geometry_t]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
            self,
 | 
					            self,
 | 
				
			||||||
            name: Union[NString, str, int],
 | 
					            name: NString | str | int,
 | 
				
			||||||
            *,
 | 
					            *,
 | 
				
			||||||
            properties: Optional[List[records.Property]] = None,
 | 
					            properties: list[records.Property] | None = None,
 | 
				
			||||||
            placements: Optional[List[records.Placement]] = None,
 | 
					            placements: list[records.Placement] | None = None,
 | 
				
			||||||
            geometry: Optional[List[records.geometry_t]] = None,
 | 
					            geometry: list[records.geometry_t] | None = None,
 | 
				
			||||||
            ) -> None:
 | 
					            ) -> None:
 | 
				
			||||||
        self.name = name if isinstance(name, (NString, int)) else NString(name)
 | 
					        self.name = name if isinstance(name, (NString, int)) else NString(name)
 | 
				
			||||||
        self.properties = [] if properties is None else properties
 | 
					        self.properties = [] if properties is None else properties
 | 
				
			||||||
@ -464,12 +461,12 @@ class CellName:
 | 
				
			|||||||
     with the reference data stripped out.
 | 
					     with the reference data stripped out.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    nstring: NString
 | 
					    nstring: NString
 | 
				
			||||||
    properties: List[records.Property]
 | 
					    properties: list[records.Property]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
            self,
 | 
					            self,
 | 
				
			||||||
            nstring: Union[NString, str],
 | 
					            nstring: NString | str,
 | 
				
			||||||
            properties: Optional[List[records.Property]] = None,
 | 
					            properties: list[records.Property] | None = None,
 | 
				
			||||||
            ) -> None:
 | 
					            ) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
@ -531,7 +528,7 @@ class XName:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Mapping from record id to record class.
 | 
					# Mapping from record id to record class.
 | 
				
			||||||
_GEOMETRY: Dict[int, Type[records.geometry_t]] = {
 | 
					_GEOMETRY: dict[int, Type[records.geometry_t]] = {
 | 
				
			||||||
    19: records.Text,
 | 
					    19: records.Text,
 | 
				
			||||||
    20: records.Rectangle,
 | 
					    20: records.Rectangle,
 | 
				
			||||||
    21: records.Polygon,
 | 
					    21: records.Polygon,
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -44,7 +44,7 @@ classifiers = [
 | 
				
			|||||||
    "Topic :: Scientific/Engineering",
 | 
					    "Topic :: Scientific/Engineering",
 | 
				
			||||||
    "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
 | 
					    "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
requires-python = ">=3.8"
 | 
					requires-python = ">=3.10"
 | 
				
			||||||
dynamic = ["version"]
 | 
					dynamic = ["version"]
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user