Skip to content

bpo-36144: Add union operators to WeakKeyDictionary #19106

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 23, 2020

Conversation

curtisbucher
Copy link
Contributor

@curtisbucher curtisbucher commented Mar 21, 2020

The __ror__ implementation was a little tricky, because we can't assume that a subclass will have the same constructor signature as the parent class, since we don't do that anywhere else.
@brandtbucher

https://bugs.python.org/issue36144

Added `_ior_`, `__or__`, and `__ror__` methods to WeakKeyDictionary and added corresponding tests to test_weakref.py.
Removed unecessary isinstance from __ior__
Added tests and modified .__ror__ behavior
@brandtbucher brandtbucher added CLA signed type-feature A feature request or enhancement labels Mar 21, 2020
@brandtbucher
Copy link
Member

Thanks for your help with these @curtisbucher! The macOS test failure looks unrelated (a bunch of other PR's have the same test failing).

Let's get this one accepted before opening another PR for WeakValueDictionary.

Copy link
Member

@brandtbucher brandtbucher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! Great job with the tests.

@brandtbucher brandtbucher requested a review from gvanrossum March 21, 2020 23:50
@gvanrossum gvanrossum changed the title bpo-36144: Add union operators to weakref.WeakKeyDictionary bpo-36144: Add union operators to WeakKeyDictionary Mar 23, 2020
Lib/weakref.py Outdated
return self

def __or__(self, other):
if isinstance(other, (dict, WeakKeyDictionary, WeakValueDictionary)):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the value of making WeakKeyDict | WeakValueDict return a WeakKeyDict? If that, why not any other Mapping? I can't think of a use case for mixing these like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So would it make more sense to have | accept any mapping and return a WeakKeyDict?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

Lib/weakref.py Outdated
return NotImplemented

def __ror__(self, other):
if isinstance(other, (dict, WeakKeyDictionary, WeakValueDictionary)):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems even more doubtful -- why would WeakValueDict | WeakKeyDict return a WeakKeyDict instead of a WeakValueDict? Aren't they symmetrical? (Also there are no tests for these mixes.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When __ror__ is used, should it always return the same type as other?

Copy link
Member

@gvanrossum gvanrossum Mar 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it should return the type of self. If other had wanted to be the return type, that class could have done so in its __or__ method, which is called before __ror__. But apparently they didn't, so it's ours.

(Here's a clarifying example for why it should be this way: Consider 1 + 2.5. int.__or__ returns NotImplemented when other is a float, so then float.__ror__ is invoked with other set to 1, and it returns the float value 3.5!)

@brandtbucher
Copy link
Member

How about just isinstance(other, _collections_abc.Mapping) then, for each?

@gvanrossum
Copy link
Member

How about just isinstance(other, _collections_abc.Mapping) then, for each?

Hm, yeah, that sounds reasonable, and it seems to be what we're doing for ChainMap and UserDict. (It seems there's a dichotomy: for classes that derive from dict we are strict, and for other classes we allow any Mapping. This seems a reasonable compromise -- maybe we can add this as a note to the PEP?)

Allow WeakKeyDictionary union with any mapping.
Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I will land once tests pass.

@gvanrossum gvanrossum merged commit 25e580a into python:master Mar 23, 2020
@bedevere-bot
Copy link

@gvanrossum: Please replace # with GH- in the commit message next time. Thanks!

@gvanrossum
Copy link
Member

Congrats on another great patch @curtisbucher !

@curtisbucher curtisbucher deleted the WeakKeyDictionary584 branch March 25, 2020 20:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants