On Thu, Aug 27, 2020, 8:34 AM Steven D'Aprano <st...@pearwood.info> wrote:

>
> > 3. Removes the need to write calls to the same supporting function in the
>
> item dunders. They are called automatically.
>
> I don't understand that sentence.
>
>
> [...]
> > My current attempt is this:
> >
> > def __subscript__(self, *args, **kwargs) -> Tuple [Tuple[Any], Dict[str,
> > Any]]:
> >     return t
>
> NameError: name 't' is not defined
>
>
> > Which, for a getitem dunder call, `t` becomes:
> >
> > obj.__getitem__(*t[0], **t[1])
>
> What does this mean? You assign
>
>     t = obj.__getitem__(*t[0], **t[1])
>
> and then return t?
>
>
> --
> Steve
>

Sorry, I need to stop coding in shorthand.

Here is a more fleshed out illustration of what I am imagining would
happen. I welcome suggestions for better ways to do pass the arguments on
to the item dunders-- the proposal remains the basic idea nugget Jonathan
Fine presented:

1. A dunder that handles the args and kwargs sent into the subscript
operator in whatever way the programmer wants (the default way, when no
such dunder is provided, being current python behavior).
2. MAGIC --- a suggestion for what the magic could be, below.
3. The appropriate item dunder is called with the parsed parameters

First, we have an example class with a new __subscript__ dunder. Remember,
the __subscript__ dunder can have any signature you want, and do anything
to the arguments inside that you want, it just needs to return something
matching the type hint below when done:

class Q:
    def __subscript__(self, a, b, c, *, x, y, z, **kwargs) ->
Sequence[Sequence[Any], Mapping[str, Any]]:
        kwargs.update(x=x, y=y, z=z)
        return (a,b,c), kwargs
    def __getitem__(self, *args, **kwargs): ...
    def __setitem__(self, __value, *args, **kwargs): ...
    def __delitem__(self, *args, **kwargs): ...

Here is what I imagine happens at the python level (but I am writing it in
python):

MISSING = object()

def cpython_subscript_operator_function(obj, *args, __item_dunder_name,
__value=MISSING, **kwargs):
    if __item_dunder_name == "__setitem__" and __value is not MISSING:
        args = (__value, *args)
    obj_class = type(obj)
    subscript_dunder =  getattr(obj_class, "__subscript__", None)
    if  subscript_dunder:
        args, kwargs =  subscript_dunder(obj, *args, **kwargs)
    return getattr(obj_class,  __item_dunder_name)(obj, *args, **kwargs)

Now, when I write this python code:

>>> q=Q()
>>> q[1, x=4, y=5, z=6, foo='bar', b=2, c=3]

That code calls this cpython pseudo code:

cpython_subscript_operator_function(q, 1, __item_dunder_name="__getitem__",
x=4, y=5, z=6, foo='bar', b=2, c=3)

And if I write set item code, it is like this:

>>> q[1, 2, 3, x=4, y=5, z=6, foo='bar'] = "baz"

cpython level call looks like:

cpython_subscript_operator_function(q, 1, __item_dunder_name="__getitem__",
__value="baz", x=4, y=5, z=6, foo='bar', b=2, c=3)
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/EPKN753OCCDUUXFA5LNHMWVHOEM2UM27/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to