Compare commits

..

8 commits

4 changed files with 20 additions and 20 deletions

View file

@ -4,7 +4,6 @@
**Homepage:** https://mpxd.net/code/jan/fatamorgana
* [PyPI](https://pypi.org/project/fatamorgana)
* [Github mirror](https://github.com/anewusername/fatamorgana)
**Capabilities:**
* This package is a work-in-progress and is largely untested -- it works for
@ -28,12 +27,7 @@
Install with pip from PyPi (preferred):
```bash
pip3 install fatamorgana
```
Install directly from git repository:
```bash
pip3 install git+https://mpxd.net/code/jan/fatamorgana.git@release
pip install fatamorgana
```
## Documentation
@ -44,7 +38,6 @@ To read the inline help,
import fatamorgana
help(fatamorgana.OasisLayout)
```
The documentation is currently very sparse and I expect to improve it whenever possible!
## Examples

View file

@ -2,7 +2,7 @@
This module contains all datatypes and parsing/writing functions for
all abstractions below the 'record' or 'block' level.
"""
from typing import Any, IO, Union
from typing import Any, IO, Union, TYPE_CHECKING
from collections.abc import Sequence
from fractions import Fraction
from enum import Enum
@ -250,6 +250,7 @@ def write_uint(stream: IO[bytes], n: int) -> int:
Raises:
SignedError: if `n` is negative.
"""
n = int(n)
if n < 0:
raise SignedError(f'uint must be positive: {n}')
@ -295,6 +296,7 @@ def encode_sint(sint: int) -> int:
Returns:
Unsigned integer encoding for the input.
"""
sint = int(sint)
return (abs(sint) << 1) | (sint < 0)
@ -1211,6 +1213,10 @@ class GridRepetition:
InvalidDataError: if `b_count` and `b_vector` inputs conflict
with each other or if `a_count < 1`.
"""
a_count = int(a_count)
if b_count is not None:
b_count = int(b_count)
if b_vector is None or b_count is None:
if b_vector is not None or b_count is not None:
raise InvalidDataError('Repetition has only one of'
@ -1595,7 +1601,7 @@ def read_point_list(
def write_point_list(
stream: IO[bytes],
points: list[Sequence[int]],
points: 'list[Sequence[int]] | NDArray',
fast: bool = False,
implicit_closed: bool = True
) -> int:
@ -1618,6 +1624,8 @@ def write_point_list(
Number of bytes written.
"""
# If we're in a hurry, just write the points as arbitrary Deltas
if _USE_NUMPY:
points = numpy.asarray(points, dtype=int)
if fast:
size = write_uint(stream, 4)
size += write_uint(stream, len(points))

View file

@ -1434,7 +1434,7 @@ class Placement(Record):
size += self.name.write(stream) # type: ignore
if mm:
size += write_real(stream, self.magnification) # type: ignore
if aa:
if aq:
size += write_real(stream, self.angle) # type: ignore
if xx:
size += write_sint(stream, self.x) # type: ignore
@ -1717,8 +1717,8 @@ class Polygon(Record, GeometryMixin):
repetition: repetition_t | None
point_list: point_list_t | None
"""
List of offsets from the initial vertex (x, y) to the remaining
vertices, `[[dx0, dy0], [dx1, dy1], ...]`.
List of offsets between consecutive vertices, starting from the initial
vertex (x, y): `[[dx0, dy0], [dx1, dy1], ...]`.
The list is an implicitly closed path, vertices are [int, int].
The initial vertex is located at (x, y) and is not represented in `point_list`.
`None` means reuse modal.
@ -1744,7 +1744,7 @@ class Polygon(Record, GeometryMixin):
self.point_list = point_list
self.properties = [] if properties is None else properties
if point_list is not None and len(point_list) < 3:
if point_list is not None and len(point_list) < 2:
warn('Polygon with < 3 points', stacklevel=2)
def get_point_list(self) -> point_list_t:
@ -1827,8 +1827,8 @@ class Path(Record, GeometryMixin):
repetition: repetition_t | None = None
point_list: point_list_t | None = None
"""
List of offsets from the initial vertex (x, y) to the remaining vertices,
`[[dx0, dy0], [dx1, dy1], ...]`.
List of offsets between consecutive vertices, starting from the initial
vertex (x, y): `[[dx0, dy0], [dx1, dy1], ...]`.
The initial vertex is located at (x, y) and is not represented in `point_list`.
Offsets are [int, int]; `None` means reuse modal.
"""
@ -1960,7 +1960,7 @@ class Path(Record, GeometryMixin):
dd = self.datatype is not None
ll = self.layer is not None
size = write_uint(stream, 21)
size = write_uint(stream, 22)
size += write_bool_byte(stream, (ee, ww, pp, xx, yy, rr, dd, ll))
if ll:
size += write_uint(stream, self.layer) # type: ignore

View file

@ -34,15 +34,14 @@ keywords = [
]
classifiers = [
"Programming Language :: Python :: 3",
"Development Status :: 3 - Alpha",
"Environment :: Other Environment",
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"Intended Audience :: Information Technology",
"Intended Audience :: Manufacturing",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: GNU Affero General Public License v3",
"Topic :: Scientific/Engineering",
"Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
"Topic :: File Formats",
]
requires-python = ">=3.11"
dynamic = ["version"]