gh-152405: Fix crash of rich-comparing MappingProxyType objects#152483
gh-152405: Fix crash of rich-comparing MappingProxyType objects#152483sobolevn wants to merge 13 commits into
MappingProxyType objects#152483Conversation
|
Would it be worth optimizing the common case where an exact (any?)dict is ultimately being compared with another exact (any?)dict. Because if it's just going to go through the dict comparison operator then it should be safe? |
|
The other variation that I was thinking about (but is untested so I might have missed a detail), is to do exact (any?)dict <-> exact (any?)dict specifically*, and then return not implemented for anything else. I think the result of that is that it would then fall back to the other classes' comparison operator, which would presumably be able to use the mapping interface of the proxy type to do the comparison. [*] possibly also with a a check for the comparison operator because the collections.OrderDict just uses the dict comparison operator |
This comment was marked as outdated.
This comment was marked as outdated.
That does suggest it might be get you a huge amount of benefit. Ah well... |
|
On more comment (then I stop thinking about this): if you're only concerned about the crash and not the leak then the only case you're really worried about is |
|
@da-woods thanks a lot for your help and ideas! I am not sure that |
I think it's just "not the dict comparison operator". I've put an alternative (draft) proposal in #152489 mostly to see if it works and passes everything. It intentionally isn't complete though and is just a quick C code suggestion right now. |
This comment was marked as outdated.
This comment was marked as outdated.
|
@da-woods please, check my new approach :) |
|
Yes - I believe that will work. It may be worth special casing not making the copy when you know the right-hand side is another exact anydict. But that's a minor implementation detail. If I was starting from scratch with no existing tests or behaviour then I think I'd prefer my approach. But obviously Python is very much not starting from scratch. So yeah - I'd agree that this fixes the important problem in the least modifying way. |
vstinner
left a comment
There was a problem hiding this comment.
Would you mind to add tests on frozendict?
|
IMO it's a good approach to fix the issue. |
vstinner
left a comment
There was a problem hiding this comment.
LGTM. Creating a copy to call __eq__() is a good fix, and the test coverage is good.
I'm fine with not fixing this issue for OrderedDict for performance reasons.
Maybe we should document that MappingProxyType doesn't fully hide the internal mapping in https://docs.python.org/dev/library/types.html#types.MappingProxyType. We can now suggest replacing MappingProxyType with frozendict which doesn't have this issue.
Sure! I will open a new PR for that :) I would love to hear other opinions before merging, let's give some time for @serhiy-storchaka or @picnixz or @methane to review this PR as well. I will keep this open for a week or so :) |
|
I reliazed that I forgot |
|
I wonder whether we really need a copy. It will undoubtly make the comparisons slower for a case that is honestly not realistic. I don't know how often people use I'm more concerned with the behavior change. Is it still a behavior change? Because that behavior change may still break code that was previously not crashing (albeit incorrect). If I were to compare two mappings like that it's hard to decide whether the |
I think that I confused you with the older outdated description.
I will only make things noticably slower for cases where we compare |
This is an alternative to #152449
Now I send a copy of the
dictif it is under a mapping, so it can't be mutated.Credit for this idea goes to @da-woods in this comment