get_net_connections() built its match-point set exclusively from wire
endpoints. If a net label was placed directly at a pin endpoint with no
wire segment (valid KiCad style), the function returned 0 connections
because connected_wire_points was empty.
Fix: build all_match_points as the union of connected wire endpoints and
label positions. Pin matching checks both, so label-at-pin schematics
produce correct netlists alongside traditional wired schematics.
Also handles the case where the schematic object has no wire attribute
at all — instead of returning early, we continue with label positions
as the sole match points.
Tests: tests/test_label_at_pin_net_connections.py (11 unit tests)
- label at pin, no wire → pin found
- label at pin, within/outside tolerance
- label via wire → still found (regression)
- mixed wired and direct labels on same net
- no wire attribute → still detects label-at-pin
- template symbols skipped
Black/isort/flake8/mypy verified manually (pre-commit local npm hook
fails to install on Windows due to MobaXterm path environment issue).