Skip to content
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

bpo-16011: Clarify behavior of __contains__ in user defined classes #152

Merged
merged 1 commit into from
Mar 28, 2017

Conversation

aktech
Copy link
Contributor

@aktech aktech commented Feb 18, 2017

>>> class Foo(object):
...     def __contains__(self, item):
            return 42
>>> foo = Foo()
>>> 3 in foo
True
>>> foo.__contains__(42)
42

@the-knights-who-say-ni
Copy link

Hello, and thanks for your contribution!

I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA).

Unfortunately our records indicate you have not signed the CLA. For legal reasons we need you to sign this before we can look at your contribution. Please follow these steps to rectify the issue:

  1. Sign the PSF contributor agreement
  2. Wait at least one US business day and then check "Your Details" on bugs.python.org to see if your account has been marked as having signed the CLA (the delay is due to a person having to manually check your signed CLA)
  3. Reply here saying you have completed the above steps

Thanks again to your contribution and we look forward to looking at it!

@aktech
Copy link
Contributor Author

aktech commented Feb 21, 2017

@tiran @ncoghlan @Mariatta Can we Merge this now, as CLA is signed?

For user-defined classes which define the :meth:`__contains__` method, ``x in
y`` is true if and only if ``y.__contains__(x)`` is true.
For user-defined classes which define the :meth:`__contains__` method, the
``in`` operator coerces the result returned by :meth:`__contains__` to a boolean,
Copy link
Member

Choose a reason for hiding this comment

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

This sentence should be ended with a full stop. Or if you used comma intentionally, "Hence" shouldn't begin with an uppercase letter "H".

y`` is true if and only if ``y.__contains__(x)`` is true.
For user-defined classes which define the :meth:`__contains__` method, the
``in`` operator coerces the result returned by :meth:`__contains__` to a boolean,
Hence ``x in y`` is true if and only if ``y.__contains__(x)`` is true.
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps changing the example to bool(y.__contains__(x)) would make the whole paragraph clearer?

Copy link
Member

Choose a reason for hiding this comment

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

+1. Otherwise I don't see the difference with the original one.

@berkerpeksag berkerpeksag changed the title bpo-16011 explicitly document the behaviour of in operator bpo-16011: Clarify behavior of __contains__ in user defined classes Feb 22, 2017
@methane
Copy link
Member

methane commented Feb 22, 2017

I feel proposed sentence is unnecessary long. How about this?

For user-defined classes which define the :meth:`__contains__` method, ``x in y``
behaves like ``bool(y.__contains__(x))``.

@aktech
Copy link
Contributor Author

aktech commented Feb 22, 2017

I have put the full stop before Hence [..].
For bool(y.__contains__(x)) quoting R. David Murray (https://bugs.python.org/issue16011) here:

"coerce to boolean" is better than "apply bool", because the code may not in fact be using the bool function to do it.

@aktech
Copy link
Contributor Author

aktech commented Feb 26, 2017

Can we merge this now?

@bitdancer
Copy link
Member

bitdancer commented Feb 27, 2017

You know what, reading this change side by side with the original, I think I'd instead favor making it:

For user-defined classes which define the :meth:`__contains__` method, ``x in y`` returns ``True`` if ``y.__contains__(x)`` returns a true value, and ``False`` otherwise.

Throughout the section, we should then change 'true' to True anywhere the result of the in operator is being discussed.

@aktech
Copy link
Contributor Author

aktech commented Mar 3, 2017

@bitdancer does that looks good now?

@bitdancer
Copy link
Member

Yes, but we should also change 'true' to True in the rest of that section where the result of 'in' is being referenced.

@aktech
Copy link
Contributor Author

aktech commented Mar 3, 2017

Yes, but we should also change 'true' to True in the rest of that section where the result of 'in' is being referenced.

Yes, Indeed. I have changed that now.

@aktech
Copy link
Contributor Author

aktech commented Mar 11, 2017

@bitdancer Is this good to go now?

substring of *y*. An equivalent test is ``y.find(x) != -1``. Empty strings are
always considered to be a substring of any other string, so ``"" in "abc"`` will
return ``True``.

For user-defined classes which define the :meth:`__contains__` method, ``x in
y`` returns ``True`` if ``y.__contains__(x)`` returns a true value, and
y`` returns ``True`` if ``y.__contains__(x)`` returns a ``True`` value, and
Copy link
Member

Choose a reason for hiding this comment

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

The second True here should be just true.

@aktech
Copy link
Contributor Author

aktech commented Mar 19, 2017

@bitdancer Can we merge this now?

@bitdancer
Copy link
Member

Not until the Travis check passes. I don't know what's wrong with that or how to get it fixed, unfortunately.

@aktech aktech force-pushed the in-contains-doc branch 2 times, most recently from 290b63f to 31fa785 Compare March 20, 2017 16:16
@aktech
Copy link
Contributor Author

aktech commented Mar 27, 2017

Not until the Travis check passes. I don't know what's wrong with that or how to get it fixed, unfortunately.

@ncoghlan Can you help me with this? Need to restart the travis build for this PR.

@ncoghlan
Copy link
Contributor

@aktech Since there isn't even a "Details" link, I can't trigger a rebuild from the Travis side of things, but you should be able to push an empty commit to the PR branch as described in http://stackoverflow.com/questions/17606874/trigger-a-travis-ci-rebuild-without-pushing-a-commit/31694534#31694534

Since we use the squash-and-merge workflow, that won't show up in the eventual commit history.

@Mariatta
Copy link
Member

Maybe try rebasing with upstream/master and push again?

Mariatta added a commit that referenced this pull request Mar 28, 2017
Mariatta added a commit that referenced this pull request Mar 29, 2017
@ncoghlan
Copy link
Contributor

Added the sprint label, as this PR was submitted at the PyCon Pune 2017 core development sprint.

@miss-islington
Copy link
Contributor

Thanks @aktech for the PR, and @bitdancer for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Sorry, @aktech and @bitdancer, I could not cleanly backport this to 2.7 due to a conflict.
Please backport using cherry_picker on command line.

akruis pushed a commit to akruis/cpython that referenced this pull request Oct 14, 2018
Preparations:
- use meaningful variable names
- remove dead code
- move the stackless addition to PyThreadState to the end of the struct
- remove redundant declarations from stackless_structs.h
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 14, 2018
Add legitimate globals to ignored-globals.txt. All other Stackless
globals should be moved to runtime or interpreter state.
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 14, 2018
It was only used during module initialization.
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 14, 2018
…time and interpreter state

Add struct _stackless_runtime_state to _PyRuntimeState and
PyStacklessInterpreterState to PyInterpreterState. For now both structs
are empty. I'll move Stackless globals into them.
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 14, 2018
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 14, 2018
…essInterpreterState

The variable holds a complex callable object, which must not be
shared between different interpreters.
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 29, 2018
Preparations:
- use meaningful variable names
- remove dead code
- move the stackless addition to PyThreadState to the end of the struct
- remove redundant declarations from stackless_structs.h
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 29, 2018
Add legitimate globals to ignored-globals.txt. All other Stackless
globals should be moved to runtime or interpreter state.
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 29, 2018
It was only used during module initialization.
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 29, 2018
…time and interpreter state

Add struct _stackless_runtime_state to _PyRuntimeState and
PyStacklessInterpreterState to PyInterpreterState. For now both structs
are empty. I'll move Stackless globals into them.
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 29, 2018
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 29, 2018
…essInterpreterState

The variable holds a complex callable object, which must not be
shared between different interpreters.
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 29, 2018
Removed globals:
- slp_initial_tstate
- channel_hook
- slp_error_handler
- _slp_schedule_fasthook
- _slp_schedule_hook
- slp_cstack_chain
- mem_bomb

Additionally I optimized the ordering of the fields of PyStacklessState
and PyStacklessInterpreterState to avoid padding.
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 29, 2018
Move slp_enable_softswitch to PyStacklessInterpreterState.
Move slp_try_stackless, cstack_cache and cstack_cachecount to
struct _stackless_runtime_state.
akruis pushed a commit to akruis/cpython that referenced this pull request Nov 1, 2018
akruis pushed a commit to akruis/cpython that referenced this pull request Nov 12, 2018
The commit used a C11 feature. Unfortunately only clang emits a warning.
jaraco pushed a commit that referenced this pull request Dec 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir sprint
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet