Skip to content

Fix normalise_args incorrectly handling bound classmethods#59

Merged
sjperkins merged 3 commits intomainfrom
fix-multiton-classmethod-interaction
Mar 31, 2026
Merged

Fix normalise_args incorrectly handling bound classmethods#59
sjperkins merged 3 commits intomainfrom
fix-multiton-classmethod-interaction

Conversation

@sjperkins
Copy link
Copy Markdown
Member

Previously, normalise_args would bind the first argument to the cls

inspect.getfullargspec includes cls in spec.args for classmethods,
but when the factory is a bound method (accessed via Class.classmethod),
cls is already bound and does not consume a positional argument at call
time. This caused normalise_args to be off-by-one on reconstruction after
pickling: an arg that was already present in the positional tuple would be
"claimed" by cls, shifting every subsequent parameter one slot forward.
The final parameter would then fall off the end and, if it had a default,
get appended again — producing a key mismatch and a TypeError at call
time (too many positional arguments).

Fix by stripping the first element of spec.args when inspect.ismethod
returns True (which covers both bound classmethods and bound instance
methods, but not plain functions or static methods).

Add three unit tests covering the classmethod case:

  • key normalisation (kw-only and positional construction are equivalent)
  • pickle round-trip (no TypeError, correct value, stdlib cache sharing)
  • default-not-duplicated (the specific failure mode from the bug)
  • Test Cases covering your PR.
  • Documentation.
  • A Changelog entry in doc/source/changelog.rst.

@sjperkins sjperkins merged commit b5f9d3b into main Mar 31, 2026
@sjperkins sjperkins deleted the fix-multiton-classmethod-interaction branch March 31, 2026 12:57
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