
On 6 Nov 2008, at 20:31, George Sakkis wrote:
Several times I find myself using the following idiom:
_Missing = object() # sentinel
def foo(x, y=_Missing): if y is _Missing: do_this else: do_that
The reason for using a "private" sentinel is that any python object, including None, might be a valid argument. Another option is using *args or **kwds instead of y but that obfuscates unnecessarily the function signature.
It would be nice if a new object or keyword, say __missing__, was introduced as a canonical way to address this common scenario. Specifically, the only valid usages of __missing__ would be: 1. As a default argument in a callable. 2. In identity tests: <var> is __missing__ Anything else would raise either a SyntaxError (e.g. `x = __missing__`) or a RuntimeError/TypeError (e.g. `x = y` if y is __missing__). Only the interpreter could assign __missing__ to a name when binding objects to formal parameters.
If this was to be accepted, a further generalization could be to allow the `var is __missing__` expression even if `var` is not a formal parameter. This would be equivalent to:
try: var except NameError: expr = True else: expr = False
Thoughts ?
Here's a proof-of-concept decorator version: from inspect import getargspec def tell_missing(f): argnames = getargspec(f)[0][1:] def decorated(*args, **kwargs): missing = set(argnames[len(args):]) - set(kwargs) return f(missing, *args, **kwargs) return decorated
@tell_missing ... def f(missing, x, y=None, z=None): ... print "Missing arguments:", ', '.join(missing) ... f(1, 2, 3) Missing arguments: f(1, 2) Missing arguments: z f(1) Missing arguments: y, z
-- Arnaud