Skip to content

Let the incr and decr stubs accept default=None - #41

Merged
avgvi merged 1 commit into
masterfrom
fix/incr-decr-default-none
Nov 3, 2026
Merged

avgvi merged 1 commit into
masterfrom
fix/incr-decr-default-none

Conversation

@avgvi

@avgvi avgvi commented Nov 3, 2026

Copy link
Copy Markdown
Member

The type stubs reject default=None in incr and decr, which the code has always accepted: with default=None a missing or expired key raises KeyError instead of starting from a default. BaseCache in _types.pyi typed default as int, so mypy reports an arg-type error on a call such as cache.incr(key, 1, default=None):

Argument "default" to "incr" of "BaseCache" has incompatible type "None"; expected "int"  [arg-type]

This showed up when moving ai-marketplace-monitor to 5.8.2: its two counter calls in utils.py pass default=None, and the only way through was # type: ignore[arg-type].

  • Stub: BaseCache.incr and decr take default: int | None. Cache and FanoutCache inherit both and don't redeclare them. DjangoCache already accepted None, and the recipes don't declare either method.
  • Check: a new tests/typecheck_stubs.py holds calls that must type-check against the stubs: incr and decr with default=None on Cache and FanoutCache. tox -e mypy, and so the CI lint job, now checks it next to the package. pytest doesn't collect it.
  • Changelog: a CHANGELOG.md entry under Unreleased.

The runtime code is unchanged.

Checked:

  • tox -e mypy fails with the error above on the four new calls against the old stub, and passes here (mypy 2.4.1).
  • bluecheck, flake8, isortcheck, mypy and pylint pass.
  • The full test suite passes on Python 3.12 with Django 5.2 (815 passed, 2 skipped, 99% coverage).
  • stubtest reports the same on master and on this branch.

Possible follow-ups, not in this PR:

  • FanoutCache.incr and decr return None on a database timeout, but the stub says int.
  • The incr docstrings pass a float delta, which works at runtime, but the stubs allow only int.
  • __init__.pyi leaves out DjangoCache, which is exported when Django is installed, so stubtest reports it. stubtest doesn't run in CI.

@avgvi
avgvi merged commit 30df125 into master Nov 3, 2026
21 checks passed
@avgvi
avgvi deleted the fix/incr-decr-default-none branch November 3, 2026 04:24
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