On Wed, 15 Jun 2022 at 20:45, Mathew Elman <mathew.elman@ocado.com> wrote:
Could this be the behaviour of passing in an Ellipsis? e.g.
def foo(defaults_to_one=1): return defaults_to_one
assert foo(...) == foo()
def bar(something=...): return foo(something)
assert bar() == foo()
def baz(arg): # no defaults return arg
assert baz(...) == ...
The only place that I am aware of the Ellipsis being used is in index notation (numpy). So this would have likely an impact on __getitem__ or the slice object.
*Alternatively* a subtype of Ellipses specifically for when used in argument defaults DefaultEllipsis (or equivalent): def foo(x=...): return x
assert isinstance(foo(), EllipsisType) assert foo() != Ellipsis
assert isinstance(foo(...), EllipsisType) assert foo(...) == Ellipsis
No, because Ellipsis is a very real object and could be passed as a parameter at any time. Although, since it's unusual, it's actually a slightly deoptimized case in my reference implementation - or rather, whenever a function observes that it's been passed Ellipsis, it checks to see if the parameter was actually omitted. Fundamentally, Python does not have any value that indicates the lack of a value. And having worked with a number of JavaScript APIs where undefined is used as "absent", I don't want to inflict that on anyone. (For instance, classList.toggle("some-class", X) will add the class if X is truthy, remove it if it's falsy, but... toggle if X is undefined. Which is otherwise falsy. Extremely annoying to try to track down.) The standard way in Python to indicate "no value" is to raise an exception instead of returning, but that doesn't work for parameters. You can use sequence unpacking to achieve that sort of effect, though. foo(*([] if x is ... else [x])) This will skip the parameter if x is Ellipsis. Obviously, you use this only when you know you'll never use Ellipsis as an actual value, though, so this can't be done in the language, but it could be useful. ChrisA