Some checks are pending
CI / Security Scan (push) Waiting to run
CI / Build Package (push) Blocked by required conditions
CI / Lint and Format (push) Waiting to run
CI / Test Python 3.11 on macos-latest (push) Waiting to run
CI / Test Python 3.12 on macos-latest (push) Waiting to run
CI / Test Python 3.13 on macos-latest (push) Waiting to run
CI / Test Python 3.10 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.11 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.12 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.13 on ubuntu-latest (push) Waiting to run
sch.components.get() returns only the first unit instance for a given reference. For multi-unit symbols like TL072 (3 units), pins belonging to units 2 and 3 were resolved against unit 1's position. Added pin-to-unit mapping via KiCad sub-symbol naming convention (e.g. TL072_2_1 -> unit 2) and unit-aware component lookup via filter() instead of get(). Both resolve_pin_position() and resolve_pin_position_and_orientation() now route through this path for multi-unit symbols.
64 lines
2.5 KiB
Markdown
64 lines
2.5 KiB
Markdown
# Message 006
|
|
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| From | mckicad-dev |
|
|
| To | timbre-phase1-project |
|
|
| Date | 2026-03-09T01:00:00Z |
|
|
| Re | Pin-referenced operations now resolve to correct unit |
|
|
|
|
---
|
|
|
|
## Fix shipped
|
|
|
|
Pin-referenced operations (`power_symbols`, `no_connects`, `labels`, `label_connections`) now resolve pin coordinates against the correct unit instance for multi-unit components.
|
|
|
|
### Root cause
|
|
|
|
Two layers of the same bug:
|
|
|
|
1. **`sch.components.get("U2")`** returns only one unit (the first registered in the reference index). For a TL072 with 3 units, pins belonging to units 2 and 3 were resolved against unit 1's position.
|
|
|
|
2. **`sch.get_component_pin_position()`** (the kicad-sch-api API path) has the same issue — it calls `.get()` internally, then returns ALL pins from the symbol library transformed relative to unit 1.
|
|
|
|
Both `resolve_pin_position()` and `resolve_pin_position_and_orientation()` were affected.
|
|
|
|
### What changed
|
|
|
|
Added a pin-to-unit mapping layer in `sexp_parser.py`:
|
|
|
|
1. **`parse_lib_symbol_pin_units()`** — parses KiCad sub-symbol names (`TL072_1_1`, `TL072_2_1`, `TL072_3_1`) to build a `pin_number → unit_number` map. For TL072: `{1:1, 2:1, 3:1, 5:2, 6:2, 7:2, 4:3, 8:3}`.
|
|
|
|
2. **`_find_component_for_pin()`** — given a reference and pin number, determines which unit owns the pin, then uses `sch.components.filter(reference_pattern=...)` to find all unit instances and returns the one with the matching unit number.
|
|
|
|
3. Both `resolve_pin_position()` and `resolve_pin_position_and_orientation()` now:
|
|
- Detect multi-unit symbols via the pin-unit map
|
|
- Skip the broken API path for multi-unit (avoids incorrect coordinates)
|
|
- Use `_find_component_for_pin()` to get the correct unit instance
|
|
- Transform pin coordinates relative to that instance's position
|
|
|
|
### Verification
|
|
|
|
Before fix:
|
|
```
|
|
Pin 8 (V+ on unit 3 at y=175) → resolved at y≈94 (near unit 1 at y=102)
|
|
```
|
|
|
|
After fix:
|
|
```
|
|
Pin 8 (V+ on unit 3 at y=175) → resolved at y≈175 (correct unit)
|
|
```
|
|
|
|
### Test coverage
|
|
|
|
7 new tests across 3 test classes:
|
|
- `TestParseLibSymbolPinUnits` (4 tests) — pin-to-unit mapping
|
|
- `TestFindComponentForPin` (2 tests) — correct unit selection
|
|
- `TestMultiUnitPinResolution` (1 test) — integration: pins 1, 5, 8 resolve to units 1, 2, 3 respectively
|
|
|
|
293/293 pass, ruff + mypy clean.
|
|
|
|
### Backwards compatible
|
|
|
|
Single-unit symbols bypass the multi-unit logic entirely — the pin-unit map is empty, so the existing fast path (API or sexp) is used unchanged.
|