Skip to content

refactor(api)!: drop Timing class; emit signed list[int] from get_raw_timings#17

Closed
balloob wants to merge 2 commits into
flipper-ir-loaderfrom
drop-timing-class
Closed

refactor(api)!: drop Timing class; emit signed list[int] from get_raw_timings#17
balloob wants to merge 2 commits into
flipper-ir-loaderfrom
drop-timing-class

Conversation

@balloob
Copy link
Copy Markdown
Contributor

@balloob balloob commented Apr 18, 2026

Summary

Replaces the Timing dataclass with a flat list[int] return type on Command.get_raw_timings(), using the signed-microsecond convention (positive = mark, negative = space) shared by ESPHome, IRremoteESP8266, and most Python IR tooling.

Closes #15.

Why

  • Less memory pressure. 34 Timing allocations per NEC call × 39 commands = 1326 dataclass instances for the bundled LG TV set alone. The new representation stores only ints (small ints are cached).
  • Matches the ecosystem. ESPHome remote_transmitter, IRremoteESP8266 sendRaw, LIRC, and Flipper .ir all use flat lists; home-assistant/core consumers already flatten pairs on every call.
  • Removes the low_us=0 smell. The trailing end pulse is now a single positive int instead of a fake-zero pair. See the previous NECCommand at commands.py:111 / :125.
  • Prior art. rf-protocols made the same switch in PR #2 / commit 846d351; downstream core PRs (core#168447, core#168448, core#168450) all got shorter.

Breaking change

  • infrared_protocols.Timing is removed.
  • Command.get_raw_timings() returns list[int] (signed µs) instead of list[Timing].

Downstream integrations become:

# Before (esphome)
timings = [
    interval
    for timing in command.get_raw_timings()
    for interval in (timing.high_us, -timing.low_us)
]
# After
timings = command.get_raw_timings()
# Before (smlight — unsigned)
timings = [
    interval
    for timing in command.get_raw_timings()
    for interval in (timing.high_us, timing.low_us)
]
# After
timings = [abs(t) for t in command.get_raw_timings()]

Draft

Stacked on flipper-ir-loader. Depends on that branch landing first; target base will move to main once the parent merges. Release as 2.0.0 because of the signature break.

Test plan

  • pytest — existing test_commands.py rewritten for list[int], all 18 tests pass
  • ruff check + ruff format --check
  • Downstream: home-assistant/core branch migrating lg_infrared, esphome, smlight, and kitchen_sink consumers (not yet pushed)

`Command.get_raw_timings()` now returns a flat `list[int]` of signed
microseconds (positive = mark, negative = space), matching the convention
used by ESPHome, IRremoteESP8266, and most Python IR tooling. The `Timing`
dataclass is gone.

This removes per-pulse dataclass instantiation (34 `Timing` objects per
NEC call × 39 commands = 1326 for the bundled LG TV set alone), cleans
up the `low_us=0` end-pulse workaround into a single trailing positive
int, and lets downstream integrations pass timings straight through
instead of flattening pairs at the call site.

BREAKING CHANGE: `get_raw_timings()` returns `list[int]` instead of
`list[Timing]`. `infrared_protocols.Timing` is removed.

Closes #15

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@balloob balloob changed the title Drop Timing class; emit signed list[int] from get_raw_timings [refactor] drop Timing class; emit signed list[int] from get_raw_timings Apr 18, 2026
@balloob balloob changed the title [refactor] drop Timing class; emit signed list[int] from get_raw_timings refactor(api)!: drop Timing class; emit signed list[int] from get_raw_timings Apr 18, 2026
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