Summary
I want to propose a language feature that allows a function argument to be conditionally omitted directly at the call site using a bare inline if. The idea aims to provide a concise and natural way to skip passing an argument so that the function default applies, without duplicating calls or relying on boilerplate patterns. I am asking for feasibility and design feedback, and I do not have knowledge of Python grammar rules or CPython implementation details.
The idea
The proposal is that a function argument could be written with a bare inline if. If the condition is true, the value is passed. If it is false, the argument is omitted entirely.
Example:
def fetch_data(user_id: int, timeout: int = 10) -> None:
"""
Hypothetical API call.
timeout: network timeout in seconds, defaults to 10
"""
timeout: int | None = ... # Could be an int or None.
user_id: int = 42
fetch_data(
user_id,
timeout = timeout if timeout # passes only if timeout is not None; or if timeout is truthy.
)
Meaning:
- if
timeoutevaluates true, the argument is passed - otherwise, it is omitted and the function uses the default value 10
This feels conceptually familiar because it matches how we currently write an external if statement that conditionally calls a function with or without the argument. The proposed inline form removes duplication while keeping the intention clear and close to the call site.
I also considered a keyword like omit or a soft keyword, for example:
timeout = timeout if condition else omit
but this becomes more verbose, so I am not suggesting it as the preferred form.
Why this is needed
Current Python patterns for conditionally omitting arguments work, but each has significant drawbacks. None provide a clean or elegant call-site level expression of the intention. The lack of a direct mechanism forces developers to choose between duplication and extra machinery.
Existing workarounds and their weaknesses
1. Duplicating the call with a surrounding if
if timeout:
return fetch_data(user_id, timeout=timeout)
return fetch_data(user_id)
When multiple optional arguments are involved, this quickly becomes repetitive. It also splits the function call across control flow branches, making it harder to visually parse.
2. Building a temporary kwargs dict
kwargs = {}
if timeout:
kwargs["timeout"] = timeout
if retries:
kwargs["retries"] = retries
fetch_data(user_id, **kwargs)
This introduces boilerplate, an extra mutable object, and complicates type checking since the temporary mapping must be typed separately. It also separates the argument from the call site.
3. Inline dict unpacking
fetch_data(
user_id,
**({"timeout": timeout} if timeout else {}),
**({"retries": retries} if retries else {})
)
This is compact but visually noisy. It hides the arguments under an unpacking expression rather than keeping them in their natural keyword positions. Type checkers also have difficulty tracking the eventual keywords.
4. Repeating the default values
fetch_data(
user_id,
timeout = timeout if timeout else 10,
retries = retries if retries else 3
)
This duplicates the default values, which becomes incorrect if the function signature changes. It also breaks the connection between the defaults defined by the function and the defaults used at the call site.
5. Using None as a sentinel and reassigning inside the function
def fetch_data(user_id, timeout=None, retries=None):
if timeout is None:
timeout = 10
if retries is None:
retries = 3
This shifts responsibility into the function and requires altering the function’s design purely because the call site cannot omit arguments conditionally.
Why the current situation lacks elegance
All existing patterns either duplicate work, obscure intent, introduce unnecessary containers, or disconnect the function’s default from the call site. None directly express the simple intention: omit this argument when a condition fails.
The proposed inline form keeps the argument exactly where it belongs, expresses the logic concisely, and avoids external scaffolding.
Questions for evaluation
I would like feedback on feasibility and design:
- Is such inline conditional omission syntactically and conceptually acceptable for Python
- Would this create ambiguity or parsing challenges
- Can CPython’s grammar support conditional omission without major complexity
- Are there fundamental reasons why omission must stay outside the call site rather than being expressed inline
- If this concept is workable, could it justify becoming a formal PEP
I am especially interested in whether this fits Python’s design philosophy and whether the parser or call mechanism makes it impractical.