v2.4.0
v2.4.0
Eighteen merges since v2.3.1. Four new tool families land — symbol library management, symbol property editing, lib_id replacement for library migration, and update-from-library refresh — alongside a process-wide caching layer for symbol discovery. Two fixes restore basic operation for whole classes of users: every .kicad_sym and schematic write was broken on Python 3.9, and JLCPCB part search could not find hyphenated MPNs.
Highlights
New tool families:
- Library management:
import_symbol/export_symbol/rename_symbol(#317) -- copy a symbol between.kicad_symlibraries (with optional rename/overwrite; target created if missing), extract one symbol to a standalone file, and rename a symbol including its sub-symbol shards and any(extends ...)references from derived symbols in the same library - Symbol property tools (#308) --
add_symbol_propertysets custom BOM fields (Manufacturer, MPN, LCSC, ...) on a symbol in a.kicad_symlibrary file;add_library_symbol_propertydoes the same on a schematic's cached definition update_symbol_from_library(#291) -- refresh cachedlib_symbolsdefinitions in one schematic, a list, or every project under a directory, preserving placed instances -- the programmatic equivalent of KiCad's Update Symbol from Libraryreplace_instance_lib_ids(#316) -- swaplib_idreferences per an explicit old-to-new mapping for migrating schematics between libraries, with automatic angle correction for the Eagle importer's mirror-variant suffixes
Performance:
- Process-wide symbol discovery caches (#320) -- library directories, resolved paths, extracted symbol blocks, and parsed symbol lists were rebuilt on every component add, re-reading multi-MB
.kicad_symfiles each time; they are now cached process-wide with staleness guards (mtime_nstracking, path revalidation, explicit invalidation on every mutating write) sync_schematic_to_boardcaches its LibraryManager (#310) -- no longer re-parses the fp-lib-table on every call
Bug fixes:
- Python 3.9 writes restored (#328) --
Path.write_text(newline=)is only accepted from Python 3.10, so on the project's declared 3.9 floor every library-management, Eagle-prettify, and symbol-schematic write raisedTypeError; all sites now open the file handle explicitly, preserving forced LF line endings - JLCPCB search finds hyphenated MPNs (#327) -- FTS5 reads
-as a column/NOT operator, so searching a real MPN likeSHT41-AD1F-R2raisedOperationalError, which a broadexceptswallowed into an empty result -- exact-MPN searches silently found nothing; each term is now emitted as a quoted prefix phrase so FTS punctuation matches as literal text - Eagle import writes KiCad 10 headers (#330, closes #321) -- generated
.kicad_schfiles carried the KiCad 920250114token; they now carry the canonical KiCad 10 header, verified by exporting the importer's output to PDF and running ERC with realkicad-cli10.0 - Component placement snaps to the 1.27 mm grid (#319, closes #299) -- library pins sit at multiples of 1.27 mm from the symbol origin, so an off-grid origin left every pin off-grid: wires and net labels could not bind, ERC reported
endpoint_off_grid, and the netlist came up empty import_sesno longer creates phantom slashless nets (#309, fixes #246) -- Freerouting strips the leading/from global net names; routed tracks now bind to the original netsexport_dsn/autoroutekeep.kicad_pronet classes (#306, fixes #302) -- power/ground clearance and width rules were silently dropped from the Specctra DSN_find_pins_on_netlocates pins on rotated symbols (#304, fixes #303) -- used a local transform instead of world coordinatesadd_sheet_pinfinds sheets regardless of line formatting (#307, fixes #298)- Test-suite state pollution eliminated (#312, fixes #287) -- a leaked
sys.modulesentry caused order-dependent pin-position failures - Freerouting runs headless (#313) -- autoroute no longer opens a GUI window
Tooling:
- pathlib migration, first slice (#254) --
kicad_interface.pyandschematic_handlers.pynow usepathlib.Path; note the mypy target is now 3.10, so the declared 3.9 floor is no longer type-checker-verified (the #328 crash is exactly the class of breakage this leaves to review) - Interface construction smoke test -- a handler class that references an unimported function now fails tests instead of crashing the server at startup (#308 shipped exactly that)
- CHANGELOG lint (#322) -- inline code spans crossing line breaks tripped prettier's list-indentation logic on every reformat; a regression test now guards it
Issues closed
#246, #287, #298, #299, #302, #303, #321
Full details in CHANGELOG.md.