Skip to content

refactor(mcuboot): contain TLV info magics in the type system#115

Merged
JPHutchins merged 1 commit into
mainfrom
refactor/protoected-tlv
Jun 11, 2026
Merged

refactor(mcuboot): contain TLV info magics in the type system#115
JPHutchins merged 1 commit into
mainfrom
refactor/protoected-tlv

Conversation

@JPHutchins

Copy link
Copy Markdown
Collaborator

Summary

  • ImageMagic, ImageTLVInfoMagic, and ImageTLVProtInfoMagic Literal type aliases tie each magic constant to its type (Literal[...] cannot reference a Final name per PEP 586, so the constants are typed Final[<alias>] to keep the value and type checked against each other).
  • ImageTLVInfo is now generic over its magic, so protected and unprotected TLV info regions are distinct static types. The expected magic argument to loads/load_from binds the type parameter and supplies the runtime check, replacing the protected: bool flag. The loaders use a method-scoped TypeVar (MagicT) because class-scoped TypeVars only bind via self/cls — verified against both mypy and pyright.
  • ImageTLVInfo.load_tlvs_from(file) reads and parses the TLV entries that follow the header, removing the tlv_tot - IMAGE_TLV_INFO_STRUCT.size wire-format arithmetic from ImageInfo.load_file.
  • ImageHeader bad-magic validation moves from __post_init__ (made unreachable by pydantic Literal validation) into loads, preserving MCUBootImageError on the load path.
  • Tests: assert_type checks pin the static types at call sites, and new error-path tests bring smpclient/mcuboot.py to 100% line and branch coverage.

Breaking changes

  • ImageTLVInfo.loads/load_from take a required magic argument instead of protected: bool = False.
  • ImageTLVInfo.REGION_SIZE is removed — use IMAGE_TLV_INFO_STRUCT.size.
  • ImageInfo.protected_tlvs defaults to None instead of [], pairing with protected_tlv_info.

Test plan

  • task format, task lint, task typecheck (mypy), full task test — 296 passed
  • pyright clean on mcuboot.py and test_mcuboot_tools.py (loaders infer ImageTLVInfo[Literal[0x6907]]/[Literal[0x6908]], no Unknown)
  • 100% line and branch coverage on smpclient/mcuboot.py

🤖 Generated with Claude Code

- ImageMagic, ImageTLVInfoMagic, and ImageTLVProtInfoMagic Literal types
  tie each magic constant to its type; ImageHeader.magic and
  ImageTLVInfo.magic are no longer plain int
- ImageTLVInfo is generic over its magic so protected and unprotected
  TLV info regions are distinct static types; the expected magic
  argument to loads/load_from binds the type parameter and supplies the
  runtime check, replacing the protected: bool flag
- ImageTLVInfo.load_tlvs_from reads and parses the TLV entries that
  follow the header, removing the wire-format arithmetic from
  ImageInfo.load_file
- ImageHeader bad-magic validation moves from __post_init__ (made
  unreachable by pydantic Literal validation) into loads, preserving
  MCUBootImageError on the load path

BREAKING CHANGE: ImageTLVInfo.REGION_SIZE is removed (use
IMAGE_TLV_INFO_STRUCT.size); ImageInfo.protected_tlvs defaults to None
instead of []; ImageTLVInfo.loads/load_from take a required magic
argument instead of protected: bool

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 11, 2026 20:32
@JPHutchins

Copy link
Copy Markdown
Collaborator Author

FYI @ChapterSevenSeeds - stronger typing for mcuboot types, claude pass for "100% coverage".

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the MCUBoot image parsing utilities to encode MCUBoot “magic” constants (image header magic and TLV info/protected TLV info magics) directly in the type system using Literal aliases and a generic ImageTLVInfo[T]. It simplifies TLV parsing by moving “read following TLVs” logic onto the TLV-info header type and strengthens error-path behavior with additional tests.

Changes:

  • Introduces Literal-backed magic types (ImageMagic, ImageTLVInfoMagic, ImageTLVProtInfoMagic) and makes ImageTLVInfo generic over its magic.
  • Updates TLV-info loading APIs to require an explicit expected magic (replacing the previous protected: bool flag) and adds ImageTLVInfo.load_tlvs_from(...) to encapsulate TLV-region parsing.
  • Adjusts ImageInfo protected TLV fields (protected_tlvs now None by default) and expands tests with type-binding assertions and additional error-path coverage.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/smpclient/mcuboot.py Refactors magic constants into Literal types, generifies TLV-info headers, moves magic validation to load paths, and encapsulates TLV region parsing.
tests/test_mcuboot_tools.py Adds assert_type checks for the new generic types and expands regression/error-path test coverage for the refactor.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@JPHutchins JPHutchins merged commit f14fcac into main Jun 11, 2026
29 checks passed
@JPHutchins JPHutchins deleted the refactor/protoected-tlv branch June 11, 2026 20:38
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.

2 participants