Mailing List Archive

Fallback for operator and other dunder methods
To illustrate what I was trying to achieve:

class A:
def __init__(self, arr):
self.arr = arr

def __getattr__(self, name):
arr_method = getattr(self.arr, name)
def wrapper(*args, **kwargs):
new_arr = arr_method(*args, **kwargs)
return type(self)(new_arr)
return wrapper

a = A(np.ones((1, 1)))
print(a.sum().arr) # 1
print(a + 1) # TypeError: unsupported operand type(s) for +: 'A' and 'int'

Is there a way to achieve it without actually implementing operators?
I have looked at Proxy objects, but they do not seem suited to achieve this. (e.g. wrapt)

If there is no way to do this, wouldn’t it be sensible to have a new method, say ‘__getattrspecial__’? Either with ability to customise for which operators it is being called or not.


—Nothing ever dies, just enters the state of deferred evaluation—
Dg

--
https://mail.python.org/mailman/listinfo/python-list
Re: Fallback for operator and other dunder methods [ In reply to ]
On Wed, 26 Jul 2023 at 12:23, Dom Grigonis via Python-list
<python-list@python.org> wrote:
> print(a + 1) # TypeError: unsupported operand type(s) for +: 'A' and 'int'
>
> Is there a way to achieve it without actually implementing operators?
> I have looked at Proxy objects, but they do not seem suited to achieve this. (e.g. wrapt)

These kinds of special methods are not looked up on the object, but on
the type. It's more like type(a).__add__(a, 1). So you would need a
metaclass for this.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Fallback for operator and other dunder methods [ In reply to ]
Could you give an example? Something isn’t working for me.

> On 26 Jul 2023, at 09:40, Chris Angelico via Python-list <python-list@python.org> wrote:
>
> On Wed, 26 Jul 2023 at 12:23, Dom Grigonis via Python-list
> <python-list@python.org> wrote:
>> print(a + 1) # TypeError: unsupported operand type(s) for +: 'A' and 'int'
>>
>> Is there a way to achieve it without actually implementing operators?
>> I have looked at Proxy objects, but they do not seem suited to achieve this. (e.g. wrapt)
>
> These kinds of special methods are not looked up on the object, but on
> the type. It's more like type(a).__add__(a, 1). So you would need a
> metaclass for this.
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: Fallback for operator and other dunder methods [ In reply to ]
On Wed, 26 Jul 2023 at 16:52, Dom Grigonis <dom.grigonis@gmail.com> wrote:
>
> Could you give an example? Something isn’t working for me.
>

This is a metaclass:

class Meta(type):
...
class Demo(metaclass=Meta):
...

In order to catch those kinds of attribute lookups, you'll need the
metaclass to hook them. And you might need to use __getattribute__
rather than __getattr__. However, there may also be some checks that
simply look for the presence of the attribute (see: slots), so you may
find that it's even more complicated. It's usually easiest to just
create the slots you want.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Fallback for operator and other dunder methods [ In reply to ]
Dom Grigonis wrote at 2023-7-26 05:22 +0300:
> ...
>Is there a way to achieve it without actually implementing operators?
>I have looked at Proxy objects, but they do not seem suited to achieve this.

Proxying is a good approach:
you might have a look at `dm.reuse.proxy.OverridingProxy` (--> `dm.reuse`
on PyPI).
--
https://mail.python.org/mailman/listinfo/python-list
Re: Fallback for operator and other dunder methods [ In reply to ]
Tried exactly that and didn’t work. Neither __getattr__, nor __getattribute__ of meta is being invoked.

> On 26 Jul 2023, at 10:01, Chris Angelico via Python-list <python-list@python.org> wrote:
>
> On Wed, 26 Jul 2023 at 16:52, Dom Grigonis <dom.grigonis@gmail.com> wrote:
>>
>> Could you give an example? Something isn’t working for me.
>>
>
> This is a metaclass:
>
> class Meta(type):
> ...
> class Demo(metaclass=Meta):
> ...
>
> In order to catch those kinds of attribute lookups, you'll need the
> metaclass to hook them. And you might need to use __getattribute__
> rather than __getattr__. However, there may also be some checks that
> simply look for the presence of the attribute (see: slots), so you may
> find that it's even more complicated. It's usually easiest to just
> create the slots you want.
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: Fallback for operator and other dunder methods [ In reply to ]
Il giorno mercoledì 26 luglio 2023 alle 20:35:53 UTC+2 Dom Grigonis ha scritto:
> Tried exactly that and didn’t work. Neither __getattr__, nor __getattribute__ of meta is being invoked.
> > On 26 Jul 2023, at 10:01, Chris Angelico via Python-list <pytho...@python.org> wrote:
> >
> > On Wed, 26 Jul 2023 at 16:52, Dom Grigonis <dom.gr...@gmail.com> wrote:
> >>
> >> Could you give an example? Something isn’t working for me.
> >>
> >
> > This is a metaclass:
> >
> > class Meta(type):
> > ...
> > class Demo(metaclass=Meta):
> > ...
> >
> > In order to catch those kinds of attribute lookups, you'll need the
> > metaclass to hook them. And you might need to use __getattribute__
> > rather than __getattr__. However, there may also be some checks that
> > simply look for the presence of the attribute (see: slots), so you may
> > find that it's even more complicated. It's usually easiest to just
> > create the slots you want.
> >
> > ChrisA
> > --
> > https://mail.python.org/mailman/listinfo/python-list


For numpy arrays you can find some suggestion at:
https://numpy.org/doc/stable/user/basics.dispatch.html
--
https://mail.python.org/mailman/listinfo/python-list
Re: Fallback for operator and other dunder methods [ In reply to ]
The issue was more of a wrapping around numpy array. Found the solution already. Unfortunately, there is no equivalent to __getattr__, the only way is to dynamically define them from meta. It seems it’s pretty standard to just have a collection of special method names and using them for similar cases. Well, at least it’s what I got to. __getattr__ feels very hacky for such case, so maybe it’s for the best.

> On 2 Aug 2023, at 19:54, Edmondo Giovannozzi via Python-list <python-list@python.org> wrote:
>
> Il giorno mercoledì 26 luglio 2023 alle 20:35:53 UTC+2 Dom Grigonis ha scritto:
>> Tried exactly that and didn’t work. Neither __getattr__, nor __getattribute__ of meta is being invoked.
>>> On 26 Jul 2023, at 10:01, Chris Angelico via Python-list <pytho...@python.org <http://python.org/>> wrote:
>>>
>>> On Wed, 26 Jul 2023 at 16:52, Dom Grigonis <dom.gr <http://dom.gr/>...@gmail.com <http://gmail.com/>> wrote:
>>>>
>>>> Could you give an example? Something isn’t working for me.
>>>>
>>>
>>> This is a metaclass:
>>>
>>> class Meta(type):
>>> ...
>>> class Demo(metaclass=Meta):
>>> ...
>>>
>>> In order to catch those kinds of attribute lookups, you'll need the
>>> metaclass to hook them. And you might need to use __getattribute__
>>> rather than __getattr__. However, there may also be some checks that
>>> simply look for the presence of the attribute (see: slots), so you may
>>> find that it's even more complicated. It's usually easiest to just
>>> create the slots you want.
>>>
>>> ChrisA
>>> --
>>> https://mail.python.org/mailman/listinfo/python-list
>
>
> For numpy arrays you can find some suggestion at:
> https://numpy.org/doc/stable/user/basics.dispatch.html <https://numpy.org/doc/stable/user/basics.dispatch.html>
> --
> https://mail.python.org/mailman/listinfo/python-list <https://mail.python.org/mailman/listinfo/python-list>
--
https://mail.python.org/mailman/listinfo/python-list