A positional-only parameter must be supplied by position, while a keyword-only parameter must be supplied by its declared name.
Python positional-only and keyword-only parameters: keep call roles explicit
Operation contract
The charge operation receives its amount before the slash and its fee after the star. Its signature prevents a keyword from binding the amount and prevents a second positional argument from accidentally becoming the fee. Type and range checks remain inside the body. The counter confirms that rejected binding never enters the function, which matters when its body would perform a write.
Failure and ownership boundary
A slash does not make a value immutable, and a star does not validate its type. A wrapper using arbitrary args and kwargs can hide the intended signature unless it preserves and enforces the contract. Python function arguments: avoid shared mutable defaults, Python unpacking: keyword collisions and strict record pairing and Python decorators: preserve metadata and expose wrapper behavior are related but separate mechanisms.
Working program
calls = 0
def charge(amount, /, *, fee=25):
global calls
if type(amount) is not int or amount < 0 or type(fee) is not int or fee < 0:
raise ValueError("nonnegative exact integers required")
calls += 1
return amount + fee
print("charged:", charge(125, fee=50))
for arguments, keywords in (((), {"amount": 125}), ((125, 50), {})):
try:
charge(*arguments, **keywords)
except TypeError:
print("binding rejected")
print("body calls:", calls)Output
charged: 175
binding rejected
binding rejected
body calls: 1Costs and limits
Binding this fixed signature has bounded work. Integer addition depends on digit length; a real amount field also needs an upper bound. Signature rejection happens before body-side changes, but a later failure inside the body still needs transaction handling.
Common Mistakes
- Signature shape and value validation solve different problems.
- Do not catch every TypeError as a binding failure when the function body can raise it too.
Connected lessons
Python function arguments: avoid shared mutable defaults, Python unpacking: keyword collisions and strict record pairing, Python refactoring: preserve rejected inputs as well as accepted results.
