Skip to content

Timer.init's three keyword-only overloads are blocked on PyMCU/PyMCU#447 (keyword args refused once >1 @inline overload exists) #20

Description

@begeistert

Update 2026-09-15: tried the split, found the real blocker

Split Timer.init into the three real keyword-only overloads
(mode=/period=/callback=/hard=, mode=/freq=/callback=/hard=,
mode=/tick_hz=/callback=/hard=) plus a fourth for the existing prescaler=
extension. Each one compiled on its own. Every real call through it did not:

t.init(period=500, callback=on_tick)
error: CompileError: 'init' has more than one @inline overload, and an overload is chosen by
the types of the POSITIONAL arguments, so a keyword argument cannot select one.

This is not particular to Timer.init: any name with more than one @inline overload
refuses every call that uses a keyword argument at all, filed precisely at
PyMCU/PyMCU#447. Timer.init's three MicroPython overloads are keyword-only by
definition (*, mode=..., period=None, ...) -- there is no positional call shape for them to
fall back to -- so splitting it is not just imperfect, it makes the method
uncallable the way MicroPython itself always calls it. Reverted to the single
merged signature this repo already had (init(period=0, mode=1, callback=0, prescaler=0, freq=0)), which is the only shape here that both compiles and stays callable by keyword.

This stays a permanent, structural deviation, not a "someone should decide" one: the split
this issue originally asked for is real work whenever PyMCU/PyMCU#447 lands, not before.

Original report

MicroPython's machine.Timer.init is declared in micropython-rp2-stubs as three
keyword-only overloads that share mode and callback but each accept exactly one of
period=, freq= or tick_hz=:

init(self, *, mode=PERIODIC, period=None, callback=None, hard=None)
init(self, *, mode=PERIODIC, freq=None, callback=None, hard=None)
init(self, *, mode=PERIODIC, tick_hz=None, callback=None, hard=None)

This layer's Timer.init(period=0, mode=1, callback=0, prescaler=0, freq=0) merges period
and freq into one call (deliberately: a caller can reach either unit), adds a
prescaler= low-level override the stub has no equivalent for, and takes all five as
positional-or-keyword rather than keyword-only.

Repo choice

Blocked on PyMCU/PyMCU#447 (keyword arguments refused whenever a name has more than one
@inline overload). Once that lands, splitting init into matching keyword-only
period=/freq=/tick_hz= overloads (losing the "set both" convenience, gaining
tick_hz= -- buildable on this chip as "pick whichever of the four AVR prescalers puts the
counting rate closest to what was asked, fire the callback on overflow") is
src/pymcu_micropython/machine.py-only work; the design above is written out and ready to
paste back in once #447 is fixed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions