On Sun, Sep 27, 2020 at 1:51 PM David Mertz <mertz@gnosis.cx> wrote:
On Sun, Sep 27, 2020 at 10:41 AM Stefano Borini <stefano.borini@gmail.com> wrote:
I kept the tuple as the accepted option, but I am personally open to
NoIndex as well. I am not sure how the SC would take a non-hashable, new constant to be
honest, for such a specific use case.

Would it need to be in __bulitins__ ? could it not be hidden away in a module somewhere (operator maybe?) I don't really see a reason not to put in __builtins__, but if there is resistance to that then it may not be necessary. And non-hashable is better, but not absolutely necessary either. Particularly if it's not in __builtins__, folks are unlikely to go use it as a dict key. So it could be a pretty lightweight new constant.

The key is that only the authors of classes that use this new fancy indexing behavior (and the interpreter) will need access to it -- "regular" users will never see it.

As for using an empty tuple, thanks Guido for laying out the logic so succinctly, and it does make it pretty simple that only the one index case is special. Nevertheless, I think most folks expect the special case to be at the end of the "series", not in the middle -- i.e.

four is the same as three is the same as two, one is special, and zero is not allowed.

rather than
 
four is the same as three is the same as two, one is special, and zero is the same as two, three, four, ...

For that reason, I prefer a separate sentinel.

But in fact, the number of people that write classes that use this new behavior will be orders of magnitude smaller than the number of users of such classes [*], so as long as it looks simple and consistent from the users side, anything that can be explained is fine.

The other thing to keep in mind is that even with the current, simpler situation, I suspect that a lot of people don't know that multiple indexes don't actually exist in current Python, and that the comma is not passing another index, but is actually simply making a tuple, just like it does everywhere else. It looks like passing multiple arguments to a function and, if you don't look inside the class, it acts like it too. if keyword indices are added, it will look even more like a function call.

So: it may be rare, but it would be pretty confusing if

obj[(), kw=x] is the same as: obj[kw=x]

whereas:

obj[NoIndex, kw=x] is the same as obj[kx=x]

would be less surprising, and even less likely to be stumbled upon anyway.

-CHB


--
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython