Skip to content

Update headers to Vehicle Spy 3.26.3.9; adopt 1!26.3.9 epoch versioning#234

Merged
drebbe-intrepid merged 9 commits into
masterfrom
feature/header-3.26.3.9
Jul 7, 2026
Merged

Update headers to Vehicle Spy 3.26.3.9; adopt 1!26.3.9 epoch versioning#234
drebbe-intrepid merged 9 commits into
masterfrom
feature/header-3.26.3.9

Conversation

@drebbe-intrepid

@drebbe-intrepid drebbe-intrepid commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Updates the vendored headers to Vehicle Spy 3.26.3.9 and migrates the release versioning to the Vspy-aligned scheme via a PEP 440 epoch: the next release is 1!26.3.9.

Header update (breaking)

  • icsnVC40.h copied verbatim from vspy3 Core/Hardware (hash-verified against the source tree). cicsSpyStatusBits.h was already byte-identical upstream.
  • Dropped the local icsnVC40.h.patch: upstream now carries its own pack(4) (around the icsDeviceStatus union), and matching the exact header the 3.26.3.9 icsneo40.dll was built against is the ABI-safe choice.
  • Breaking: 9 legacy device constants renamed upstream (NEODEVICE_BLUENEODEVICE_BLUE_DEPRECATED, likewise DW_VCAN, FIRE, VCAN3, RED, ECU, PENDANT, NEOANALOG, CT_OBD) and 5 legacy settings structs removed (SRedSettings, SFireSettings, SVCAN3Settings, SECUSettings, SPendantSettings). The module mirrors the header as-is — no compat aliases. Scripts using legacy devices should stay on 923.11.
  • New/grown structures: RADComet3 (918), RADGigastar2 (2400), SRADGalaxy2Settings 960→1204, new CMP_STREAMS_* constants.
  • src/methods.cpp: the 9 renamed constants updated in the legacy device-name fallback switch; display strings unchanged.
  • doc/source/index.rst regenerated against the new module surface.

Versioning migration (the pip problem)

PEP 440 orders 923.11 > 26.3.9, so a plain 26.3.9 upload would never be picked up by pip. Releases now use a version epoch — dunamai already parses epoch tags, so the only code change was making setup.py's get_version() strip the epoch before deriving MAJOR/MINOR macros.

Dry-run proof (local tag v1!26.3.9, deleted afterwards):

  • dunamai serialization: 1!26.3.9
  • wheel METADATA: Version: 1!26.3.9
  • pip install --dry-run -U with both a local 1!26.3.9 wheel and the PyPI 923.11 available: Would install python_ics-1!26.3.9

Pinning guidance is documented in the new README Versioning section. All future tags must keep the 1! prefix (v1!26.4.0, …) — a bare v26.x tag would sort below 923.11 again.

Tests

  • New tests/test_struct_sizes.py: validates every generated ctypes struct against the header's *_SIZE macros (72 matched; the only allowlisted discrepancy is upstream's stale RAD_GPTP_AND_TAP_SETTINGS_SIZE = 40 vs actual 56, unchanged in 3.26.3.9).
  • New tests/test_header_3_26.py: pins the 3.26.3.9 API surface (renames, removals, grown sizes).
  • Full suite: 30/30 pass (win_amd64, CPython 3.14.5).

Hardware verification (neoVI FIRE3, ON0569)

  • find_devices / open / get_serial_number / get_device_settings all working on the rebuilt module.
  • Ethernet TX/RX on NETID_ETHERNET2: transmitted 64-byte frame came back as a byte-exact TX report (162 messages, 0 errors). Device settings were modified RAM-only (save_to_eeprom=0) and restored (verified read-back 0x20000010 / 0x3F).
  • get_device_status() still fails (icsneoGetDeviceStatus() Failed) even with the matched header and the 26.3 driver (DLL reports 2603) — so the failure is not the old header-layout mismatch; needs a separate look at the DLL/API for FIRE3.

⚠️ Known ABI gap for Linux/macOS wheels

build_libicsneo.py stays pinned at 830fe1a, whose vendored icsnVC40.h predates 3.26.3.9 (no Comet3/Gigastar2 structs, Galaxy2 size 840 vs 1204, bare NEODEVICE_BLUE). A bump to current libicsneo master (4ed29b4) was tried and reverted: master still has the old header and adds a mandatory icspb protobuf dependency whose codegen fails on the CI wheel builders (_deps/icspb-build/protos/: No such file or directory). So until libicsneo syncs its header (and icspb builds cleanly), Linux/macOS wheels ABI-mismatch the grown/new device settings structs regardless of pin choice. Noted in a comment at the pin. (Windows uses the installed icsneo40.dll and is unaffected.)

Known issues (pre-existing, not addressed here)

  • examples/lin_settings_example.py references enum members that were deprecated/nonexistent before this branch; it was already broken and needs a rewrite or removal.
  • __full_version__ (cosmetic) uses dunamai's {base} format, which omits the epoch.

Post-merge release checklist

  1. Fix the Deploy PyPI wheel check first (pre-existing, fails on master today — run 28872960948): check-wheel-contents rejects the delvewheel-repaired Windows wheel with W009/W010 (ics/ + python_ics.libs/ toplevel). Allowlist those codes for the repaired layout or the 1!26.3.9 upload will fail the same way.
  2. Merge this PR.
  3. Before trusting Linux/macOS wheels for RADComet3/Galaxy2/Gigastar2 settings: get libicsneo's vendored icsnVC40.h synced to 3.26.3.9 upstream, then bump the pin again (see ABI-gap note above).
  4. Tag the merge commit: git tag -a "v1!26.3.9" -m "Vehicle Spy 3.26.3.9" && git push origin "v1!26.3.9".
  5. Verify PyPI shows 1!26.3.9 as latest and pip install -U python_ics upgrades a 923.11 install.

🤖 Generated with Claude Code

drebbe-intrepid and others added 9 commits July 7, 2026 12:21
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- icsnVC40.h / cicsSpyStatusBits.h copied verbatim from vspy3 Core/Hardware
- drop local icsnVC40.h.patch: upstream now carries its own pack(4)
  around icsDeviceStatus, matching what the 3.26.3.9 DLL was built against
- legacy device constants renamed *_DEPRECATED upstream; legacy settings
  structs removed (breaking; signaled by the 1!26.3.9 epoch release)
- regenerate module defines and processed headers
- adjust test_struct_sizes.py matched-macro baseline (77 -> 72): the 5
  removed legacy settings structs (SRedSettings, SFireSettings,
  SVCAN3Settings, SECUSettings, SPendantSettings) took their *_SIZE
  macros with them, a clean removal rather than a mapping regression

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
get_version() derives MAJOR/MINOR macros from the dunamai version;
strip the PEP 440 epoch prefix so builds work from v1!x.y.z tags.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- doc/source/index.rst regenerated against the new module surface
- README versioning typo; pytest main footer in test_struct_sizes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Latest upstream still vendors a pre-3.26.3.9 icsnVC40.h, so the
Linux/macOS ABI gap for grown/new device settings remains until
libicsneo syncs its header; noted at the pin.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Master (4ed29b4) adds a mandatory icspb protobuf dependency whose
codegen fails on the CI wheel builders (missing _deps/icspb-build/protos
output dir), and its vendored icsnVC40.h is still pre-3.26.3.9 — so the
bump broke Linux/macOS wheels while gaining no ABI parity. Re-bump once
upstream syncs the header and icspb builds cleanly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@drebbe-intrepid drebbe-intrepid merged commit 99d00dc into master Jul 7, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant