On Thu, Aug 27, 2020 at 09:57:26AM -0400, Ricky Teachey wrote:
> Sorry, I need to stop coding in shorthand.
That might help.
What might help even more is if you spend less time showing imaginary,
and invariably buggy, examples and more time explaining in words the
intended semantics of this, and the reason why you want those semantics.
I had to read over your email three times before the penny dropped what
you are actually saying. Partly because I haven't had breakfast yet,
partly because I was still thinking about earlier versions of your
proposal e.g. when you had a single subscript dunder get passed the name
of the get- set- or del-item dunder, and was expected to dispatch to
that method. But mostly because your description is so full of fine
detail that the big picture is missing.
So let me see if I have this. You want to add a special dunder method
which, if it exists, is automatically called by the interpreter to
preprocess the subscript before passing it to the usual get-, set- and
del-item dunders.
So instead of having this:
# hypothetical change to subscript behaviour
# to allow multiple arguments
def __getitem__(self, fee, fi, fo, fum):
...
# and similar for __setitem__ and __delitem__
We will have this:
def __subscript__(self, fee, fi, fo, fum):
return (fee, fi, fo, fum, {})
def __getitem__(self, fee, fi, fo, fum, **kw):
assert kw == {}
...
# and similar for __setitem__ and __delitem__
and the process changes from:
* interpreter passes arguments to the appropriate dunder
to this instead:
* interpreter passes arguments to the subscript dunder
* which preprocesses them and returns them
* and the interpreter then passes them to the appropriate dunder.
I'm underwhelmed.
I *think* your intention here is to handle the transition from the
status quo to full function-like parameters in subscripts in a backwards
compatible way, but that's not going to work.
The status quo is that the subscript is passed as either a single value,
or a tuple, not multiple arguments. If that *parsing rule* remains in
place, then these two calls are indistinguishable:
obj[spam, eggs]
obj[(spam, eggs)]
and your subscript dunder will only receive a single argument because
that's what the parser sees. So you need to change the parser rule.
But that breaks code that doesn't include the subscript dunder, because
now this:
obj[spam, eggs]
gets passed as two args, not one, and `__getitem__` has only been
written to accept one, so you get a TypeError.
Your subscript preprocessor would allow the coder to stick spam and eggs
into a tuple and pass it on, but it also returns a dict so the getitem
dunder still needs to be re-written to accept `**kwargs` and check that
it's empty, so you're adding more, not less, work. And besides, if I
have to add a brand new dunder method to my class in order for my item
getter to not break, it's not really backwards-compatible.
Okay, let's make the interpreter smarter: it parses spam, eggs as two
arguments, and then sees that there is no subscript dunder, so it drops
back to "legacy mode", and assembles spam and eggs into a tuple before
passing it on to the item getter.
Only that's not really backwards compatible either, because the
interpreter can't distinguish the two cases:
# single argument with trailing comma
obj[spam,]
# no trailing comma
obj[spam]
In both cases this looks like a single argument to the interpreter, but
the status quo is that they are different. The first one needs to be a
tuple of one item.
Why add all this complexity only to fail to remain backwards-compatible?
Better would be to add a new future directive to change the parsing of
subscripts, and allow people to opt-in when they are ready on a
per-module basis.
from __future__ import subscript_arguments
This sort of change in behaviour is exactly why the future mechanism was
invented. If it is desirable to change subscripting to pass multiple
positional arguments, then we should use that, not complicated jerry-
rigged "Do What I Mean" cunning plans that fail to Do What I Meant.
Notice that none of the above needs to refer to keyword arguments. We
could leave keyword arguments out of your proposal, and the argument
parsing issue remains.
--
Steve
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/SGL52P6BARYAOMQC52OOLB4GBMOETH34/
Code of Conduct: http://python.org/psf/codeofconduct/