+ 12

How is it possible to assign with == [solved]

I am confused, that this code works https://code.sololearn.com/cVsQ5fyZqtc5

8th Mar 2022, 10:31 AM
Oma Falk
Oma Falk - avatar
17 Answers
+ 11
Okay, so based on the links provided by Jayakrishna🇮🇳 and some more experimentation I think this is what is going on. MappingProxyType is merely a wrapper. There is no way to change the underlying dictionary via this wrappper. That is why proxy cannot be changed. But when you change the underlying dictionary this affects the view created with the wrapper. So any change to orig means a change to proxy. Because proxy is merely a wrapper for orig it is orig that is sent to the __eq__() function. So the reason that proxy changed despite being immutable is that despite the fact that the function is called on proxy it is actually executed on orig. And proxy is only immutable in the sense that you cannot change the underlying dictionary via proxy. But the underlying dictionary can still be changed directly. So when using MappingProxyType you have to be careful not to change the underlying dictionary if you want the view to remain unchanged.
8th Mar 2022, 3:21 PM
Simon Sauter
Simon Sauter - avatar
+ 5
A simpler code with the same weird effect: https://code.sololearn.com/cy8RD8E722CX/?ref=app
8th Mar 2022, 10:53 AM
Simon Sauter
Simon Sauter - avatar
+ 3
Actually, my initial answer was wrong, so I deleted it. I don't know why this is happening. How did you find this?
8th Mar 2022, 10:40 AM
Simon Sauter
Simon Sauter - avatar
+ 3
Not much into python so Iam not sure about it. But I found from below links related. It only Immutable at single level. Any alias reference, will change mutation.. https://stackoverflow.com/questions/41795116/difference-between-mappingproxytype-and-pep-416-frozendict https://adamj.eu/tech/2022/01/05/how-to-make-immutable-dict-in-python/
8th Mar 2022, 1:05 PM
Jayakrishna 🇮🇳
+ 3
Lisa I haven't tried it, but I assume that you can use all (or at least almost all) magic methods in a weird and counterintuitive way. The equality operator has one important distinction though. As far as I know you can use it with any two types of objects. Other magic methods like __gt__() (greater than or ">") require both arguments to be of the same type. So e.g. In my variant 2 you can replace __eq__() with __gt__() without problem because both objects have the same type. In the other examples you can't because the objects have different types.
8th Mar 2022, 7:13 PM
Simon Sauter
Simon Sauter - avatar
+ 3
Lisa Simon Sauter look at Amirs answer on my code. It is a Bug in Python language.
10th Mar 2022, 6:51 AM
Oma Falk
Oma Falk - avatar
+ 2
After thinking about this some more I think the answer is that thanks to the magic method you can use "==" for whatever function you want as long as it has two parameters. And that function can include value assignment. But I definitely would not recommend doing it unless you want to *really* annoy whoever has to maintain the code.
8th Mar 2022, 11:00 AM
Simon Sauter
Simon Sauter - avatar
8th Mar 2022, 11:10 AM
Simon Sauter
Simon Sauter - avatar
+ 2
Simon Sauter MappingProxyType is immutable. Makes things a bit more weird.
8th Mar 2022, 11:26 AM
Oma Falk
Oma Falk - avatar
+ 2
Simon Sauter thanks. I tried it with the example codes and it only appears for ==, e.g. not for neq? Following the explanations in this thread, it happens for the MappingProxyType because it already overloads ==. Do I understand it correctly?
8th Mar 2022, 7:19 PM
Lisa
Lisa - avatar
+ 2
Lisa here's an example using __neg__() to assign a value (actually instead of assigning a different number you could just as well assign an object of a completely different type): https://code.sololearn.com/cVEzKJXe7wsC/?ref=app
8th Mar 2022, 7:47 PM
Simon Sauter
Simon Sauter - avatar
+ 2
I wouldn't call it a bug and think the decision to reject the bug report was correct. The fact that the underlying dictionary can be changed is intended and mentioned in the documentation. The fact that the underlying dictionary is sent to functions is necessary. And as people pointed out in the bug report discussion doing so in a safe(r) way would be difficult and kind of overkill. I don't know if there is a necessity for allowing to (ab)use __eq__() in the way done here. But since this is hardly something anyone will do accidentally I don't see a good reason for restricting it. I think this is a case where the python principle that "we are all consenting adults here" should apply. The fact that these taken together can be used like this is not really a problem, given that this seems to be an "artifical" use that probably will never occur by accident.
10th Mar 2022, 5:50 PM
Simon Sauter
Simon Sauter - avatar
+ 1
I'm afraid things are only getting weirder: https://code.sololearn.com/c5sq3GvO6Mc9/?ref=app
8th Mar 2022, 11:51 AM
Simon Sauter
Simon Sauter - avatar
+ 1
There are actually two weird things here. 1. Why does "other" refer to orig instead of proxy? 2. Why does changing orig this way affect proxy?
8th Mar 2022, 12:13 PM
Simon Sauter
Simon Sauter - avatar
+ 1
It is specific to the equality operator?
8th Mar 2022, 12:24 PM
Lisa
Lisa - avatar
+ 1
The trick here is to use the magic method of one class to change an object of a different class. That's necessary since we don't want to change the definition of the MappingProxyType class. So we need a method that works with objects of two different types. And that is just __eq__(). When you can change the definition of your class at will you can use other magic methods the same way. As I said, in my variant 2 you can use other methods because the objects are of weird_object type.
8th Mar 2022, 7:28 PM
Simon Sauter
Simon Sauter - avatar
- 1
Compare to, ==.
10th Mar 2022, 10:26 AM
Asim Farheen ⭐⭐🤺👿👿
Asim  Farheen ⭐⭐🤺👿👿 - avatar