Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Commit

Permalink
Fix tests and formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
mawildoer committed Nov 6, 2024
1 parent 80adb8b commit 0f4d2fd
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 159 deletions.
6 changes: 3 additions & 3 deletions src/faebryk/core/reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ def __construct__(self, obj: Node) -> None:
return None


def reference[
O: Node
](out_type: type[O] | None = None, optional: bool = False) -> O | Reference:
def reference[O: Node](
out_type: type[O] | None = None, optional: bool = False
) -> O | Reference:
"""
Create a simple reference to other nodes properly encoded in the graph.
Expand Down
5 changes: 4 additions & 1 deletion src/faebryk/exporters/schematic/kicad/skidl/debug_draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ def draw_text(
font.render_to(scr, (pt.x, pt.y), txt, color)


def draw_part(part: "Part", scr: "pygame.Surface", tx: Tx, font: "pygame.font.Font", **options):
def draw_part(
part: "Part", scr: "pygame.Surface", tx: Tx, font: "pygame.font.Font", **options
):
"""Draw part bounding box.
Args:
Expand Down Expand Up @@ -185,6 +187,7 @@ def draw_part(part: "Part", scr: "pygame.Surface", tx: Tx, font: "pygame.font.Fo

# TODO: remove debug things
import pygame

pygame.draw.circle(scr, (255, 0, 0), (100, 100), 10)
pygame.draw.circle(scr, (0, 255, 0), (150, 100), 10)
pygame.draw.circle(scr, (0, 0, 255), (100, 150), 10)
Expand Down
26 changes: 6 additions & 20 deletions src/faebryk/exporters/schematic/kicad/skidl/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def to_mms(mils):

class Tx:
"""Transformation matrix."""

ROT_CCW_90: "Tx"

ROT_CW_0: "Tx"
Expand Down Expand Up @@ -204,26 +205,11 @@ def _check(tx: Tx) -> bool:

# Some common rotations.
# DANGER! These keywords are out of order!
Tx.ROT_CCW_90 = Tx(
a=0, b=1,
c=-1, d=0
)
Tx.ROT_CW_0 = Tx(
a=1, b=0,
c=0, d=1
)
Tx.ROT_CW_90 = Tx(
a=0, b=-1,
c=1, d=0
)
Tx.ROT_CW_180 = Tx(
a=-1, b=0,
c=0, d=-1
)
Tx.ROT_CW_270 = Tx(
a=0, b=1,
c=-1, d=0
)
Tx.ROT_CCW_90 = Tx(a=0, b=1, c=-1, d=0)
Tx.ROT_CW_0 = Tx(a=1, b=0, c=0, d=1)
Tx.ROT_CW_90 = Tx(a=0, b=-1, c=1, d=0)
Tx.ROT_CW_180 = Tx(a=-1, b=0, c=0, d=-1)
Tx.ROT_CW_270 = Tx(a=0, b=1, c=-1, d=0)

# Some common flips.
Tx.FLIP_X = Tx(a=-1, b=0, c=0, d=1)
Expand Down
4 changes: 3 additions & 1 deletion src/faebryk/exporters/schematic/kicad/skidl/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ def __init__(
title="",
flatness=0.0,
):
logger.debug(f"Creating node {top_name=} with {circuit=} and {len(self.all_created_nodes)=}")
logger.debug(
f"Creating node {top_name=} with {circuit=} and {len(self.all_created_nodes)=}"
)
self.all_created_nodes.append(self)
self.parent = None
self.children = defaultdict(
Expand Down
55 changes: 26 additions & 29 deletions src/faebryk/exporters/schematic/kicad/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@
from faebryk.exporters.schematic.kicad.skidl import shims
from faebryk.libs.exceptions import FaebrykException
from faebryk.libs.geometry.basic import Geometry
from faebryk.libs.kicad.fileformats import (
C_kicad_fp_lib_table_file,
)
from faebryk.libs.kicad.fileformats import (
gen_uuid as _gen_uuid,
)
Expand All @@ -45,7 +42,6 @@
C_rect,
C_stroke,
)
from faebryk.libs.kicad.paths import GLOBAL_FP_DIR_PATH, GLOBAL_FP_LIB_PATH
from faebryk.libs.sexp.dataclass_sexp import dataclass_dfs
from faebryk.libs.util import (
FuncDict,
Expand Down Expand Up @@ -185,41 +181,42 @@ def attach_symbol(self, f_symbol: F.Symbol, sym_inst: SCH.C_symbol_instance):
Transformer.has_linked_sch_pins([pin], sym_inst)
)

def index_symbol_libraries(
self, symbol_lib_paths: PathLike | list[PathLike]
) -> None:
"""Index the symbol libraries"""
if isinstance(symbol_lib_paths, (str, Path)):
symbol_lib_paths = [Path(symbol_lib_paths)]
else:
symbol_lib_paths = [Path(p) for p in symbol_lib_paths]

for path in symbol_lib_paths:
self._symbol_files_index[path.stem] = path

def index_symbol_files(
self, fp_lib_tables: PathLike | list[PathLike], load_globals: bool = True
self,
symbol_lib_paths: PathLike | list[PathLike],
symbol_lib_search_paths: PathLike | list[PathLike],
load_globals: bool = False,
) -> None:
"""
Index the symbol files in the given library tables
"""
if load_globals:
# TODO: this should work like GLOBAL_FP_LIB_PATH,
# then pass the sym-lib-table files
raise NotImplementedError("Loading global symbol libraries not implemented")

if self._symbol_files_index is None:
self._symbol_files_index = {}

if isinstance(fp_lib_tables, (str, Path)):
fp_lib_table_paths = [Path(fp_lib_tables)]
if isinstance(symbol_lib_search_paths, (str, Path)):
symbol_lib_search_paths = [Path(symbol_lib_search_paths)]
else:
fp_lib_table_paths = [Path(p) for p in fp_lib_tables]

# non-local lib, search in kicad global lib
if load_globals:
fp_lib_table_paths += [GLOBAL_FP_LIB_PATH]

for lib_path in fp_lib_table_paths:
for lib in C_kicad_fp_lib_table_file.loads(lib_path).fp_lib_table.libs:
resolved_lib_dir = lib.uri.replace("${KIPRJMOD}", str(lib_path.parent))
resolved_lib_dir = resolved_lib_dir.replace(
"${KICAD8_FOOTPRINT_DIR}", str(GLOBAL_FP_DIR_PATH)
)

resolved_lib_dir = Path(resolved_lib_dir)

# HACK: paths typically look like .../libs/footprints/xyz.pretty
# we actually want the .../libs/ part of it, so we'll just knock
# off the last two directories
resolved_lib_dir = resolved_lib_dir.parent.parent
symbol_lib_search_paths = [Path(p) for p in symbol_lib_search_paths]

for path in resolved_lib_dir.glob("*.kicad_sym"):
if path.stem not in self._symbol_files_index:
self._symbol_files_index[path.stem] = path
for path in chain(symbol_lib_search_paths, symbol_lib_paths):
self.index_symbol_libraries(path)

@staticmethod
def flipped[T](input_list: list[tuple[T, int]]) -> list[tuple[T, int]]:
Expand Down
16 changes: 10 additions & 6 deletions src/faebryk/library/has_pcb_routing_strategy_manual.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@
# SPDX-License-Identifier: MIT

import logging
from typing import Sequence
from typing import TYPE_CHECKING, Sequence

import faebryk.library._F as F
from faebryk.core.node import Node
from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer
from faebryk.exporters.pcb.routing.util import (
Path,
Route,
get_internal_nets_of_node,
get_pads_pos_of_mifs,
)

if TYPE_CHECKING:
from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer

logger = logging.getLogger(__name__)


Expand All @@ -30,7 +32,7 @@ def __init__(
self.relative_to = relative_to
self.absolute = absolute

def calculate(self, transformer: PCB_Transformer):
def calculate(self, transformer: "PCB_Transformer"):
node = self.obj
nets = get_internal_nets_of_node(node)

Expand All @@ -56,9 +58,11 @@ def get_route_for_mifs_in_net(mifs, path):
for net_or_mifs, path in self.paths_rel
if (
route := get_route_for_mifs_in_net(
nets[net_or_mifs]
if isinstance(net_or_mifs, F.Net)
else net_or_mifs,
(
nets[net_or_mifs]
if isinstance(net_or_mifs, F.Net)
else net_or_mifs
),
path,
)
)
Expand Down
7 changes: 5 additions & 2 deletions src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
# SPDX-License-Identifier: MIT

import logging
from typing import TYPE_CHECKING

import faebryk.library._F as F
from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer
from faebryk.exporters.pcb.routing.util import (
DEFAULT_TRACE_WIDTH,
DEFAULT_VIA_SIZE_DRILL,
Expand All @@ -17,6 +17,9 @@
)
from faebryk.libs.geometry.basic import Geometry

if TYPE_CHECKING:
from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer

logger = logging.getLogger(__name__)


Expand All @@ -26,7 +29,7 @@ def __init__(self, layer: str, vec: Geometry.Point2D):
self.vec = vec
self.layer = layer

def calculate(self, transformer: PCB_Transformer):
def calculate(self, transformer: "PCB_Transformer"):
layer = transformer.get_layer_id(self.layer)

node = self.obj
Expand Down
11 changes: 7 additions & 4 deletions src/faebryk/libs/kicad/fileformats_sch.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from enum import auto
from typing import Optional

from faebryk.exporters.pcb.kicad.transformer import gen_uuid
from faebryk.libs.kicad.fileformats_common import (
UUID,
C_effects,
Expand All @@ -27,6 +26,12 @@


def uuid_field():
def gen_uuid():
# TODO: wtf? This is one heck of a circular import defense
from faebryk.exporters.pcb.kicad.transformer import gen_uuid

return gen_uuid()

return field(default_factory=gen_uuid)


Expand Down Expand Up @@ -228,6 +233,7 @@ class E_mirror(SymEnum):
Mirroring is applied about the X or Y axes
The allowed mirrors are dependent on the rotation of the part
"""

x = "x"
y = "y"

Expand Down Expand Up @@ -399,9 +405,6 @@ def skeleton(cls) -> "C_kicad_sch_file":
version=20211123,
generator="faebryk",
paper="A4",
# uuid=gen_uuid(),
# lib_symbols=C_kicad_sch_file.C_kicad_sch.C_lib_symbols(symbols={}),
# title_block=C_kicad_sch_file.C_kicad_sch.C_title_block(),
)
)

Expand Down
54 changes: 0 additions & 54 deletions test/exporters/schematic/kicad/test_skidl_gen_schematic.py
Original file line number Diff line number Diff line change
@@ -1,54 +0,0 @@
import pytest

from faebryk.exporters.schematic.kicad.skidl.shims import Part, Pin


@pytest.fixture
def part() -> Part:

part = Part()

part.pins = [Pin() for _ in range(4)]
part.pins[0].orientation = "U"
part.pins[1].orientation = "D"
part.pins[2].orientation = "L"
part.pins[3].orientation = "R"

part.pins_by_orientation = {
"U": part.pins[0],
"D": part.pins[1],
"L": part.pins[2],
"R": part.pins[3],
}

return part


@pytest.mark.parametrize(
"pwr_pins, gnd_pins, expected, certainty",
[
(["U"], ["D"], 180, 1.0),
(["L"], ["R"], 90, 1.0),
(["R"], ["L"], 270, 1.0),
([], [], 0, 0),
],
)
def test_ideal_part_rotation(part, pwr_pins, gnd_pins, expected, certainty):
from faebryk.exporters.schematic.kicad.skidl.gen_schematic import (
_ideal_part_rotation,
)

assert isinstance(part, Part)
for orientation, pin in part.pins_by_orientation.items():
assert isinstance(pin, Pin)
if orientation in pwr_pins:
pin.fab_is_pwr = True
pin.fab_is_gnd = False
elif orientation in gnd_pins:
pin.fab_is_gnd = True
pin.fab_is_pwr = False
else:
pin.fab_is_pwr = False
pin.fab_is_gnd = False

assert _ideal_part_rotation(part) == (expected, certainty)
8 changes: 4 additions & 4 deletions test/exporters/schematic/kicad/test_skidl_geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
@pytest.mark.parametrize(
"tx, expected",
[
(Tx.ROT_CCW_90, (90, False)),
(Tx.FLIP_X * Tx.ROT_CCW_90, (90, True)),
(Tx.ROT_CW_90, (270, False)),
(Tx.FLIP_X * Tx.ROT_CW_90, (270, True)),
(Tx.ROT_CCW_90, (False, 90)),
(Tx.FLIP_X * Tx.ROT_CCW_90, (True, 90)),
(Tx.ROT_CW_90, (False, 270)),
(Tx.FLIP_X * Tx.ROT_CW_90, (True, 270)),
],
)
def test_find_orientation(tx: Tx, expected: tuple[float, bool]):
Expand Down
Loading

0 comments on commit 0f4d2fd

Please sign in to comment.