diff --git a/crates/red_knot_python_semantic/resources/mdtest/comparison/instances/membership_test.md b/crates/red_knot_python_semantic/resources/mdtest/comparison/instances/membership_test.md index 4c52ad3794c4d..fde1bb6a4b29f 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/comparison/instances/membership_test.md +++ b/crates/red_knot_python_semantic/resources/mdtest/comparison/instances/membership_test.md @@ -1,13 +1,14 @@ # Comparison: Membership Test -In Python, "membership test operators" refer to `in` and `not in` operator. To -customize their behavior, classes can implement methods like `__contains__`, -`__iter__`, or `__getitem__`. +In Python, the term "membership test operators" refers to the operators +`in` and `not in`. To customize their behavior, classes can implement one of +the special methods `__contains__`, `__iter__`, or `__getitem__`. For references, see: - - +- ## Implements `__contains__` @@ -47,10 +48,11 @@ reveal_type(42 not in A()) # revealed: bool ## Implements `__getitems__` -The final fallback is to implement `__getitem__` for integer keys: Python will -call it with 0, 1, 2... until it either finds the needle (returning True for the -membership test) or `__getitem__` raises IndexError, which is silenced and -returns `False` for the membership test. +The final fallback is to implement `__getitem__` for integer keys. Python will +call `__getitem__` with `0`, `1`, `2`... until either the needle is found +(leading the membership test to evaluate to `True`) or `__getitem__` raises +`IndexError` (the raised exception is swallowed, but results in the membership +test evaluating to `False`). ```py class A: @@ -65,7 +67,7 @@ reveal_type(42 not in A()) # revealed: bool ## Wrong Return Type -Python coerces the results of containment checks to bool, even if `__contains__` +Python coerces the results of containment checks to `bool`, even if `__contains__` returns a non-bool: ```py @@ -149,7 +151,7 @@ reveal_type(CheckGetItem() in B()) # revealed: bool ## Invalid Old-Style Iteration If `__getitem__` is implemented but does not accept integer arguments, then -membership test is not supported and should emit a diagnostic. +the membership test is not supported and should trigger a diagnostic. ```py class A: diff --git a/crates/red_knot_python_semantic/resources/mdtest/comparison/instances/rich_comparison.md b/crates/red_knot_python_semantic/resources/mdtest/comparison/instances/rich_comparison.md index f0775dfbbbb97..2aaa103963936 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/comparison/instances/rich_comparison.md +++ b/crates/red_knot_python_semantic/resources/mdtest/comparison/instances/rich_comparison.md @@ -9,7 +9,7 @@ For references, see: - - -## Implements Rich Comparison Dunders For Same Class +## Rich Comparison Dunder Implementations For Same Class Classes can support rich comparison by implementing dunder methods like `__eq__`, `__ne__`, etc. The most common case involves implementing these @@ -45,7 +45,7 @@ reveal_type(A() > A()) # revealed: list reveal_type(A() >= A()) # revealed: set ``` -## Implements Rich Comparison Dunders for Other Class +## Rich Comparison Dunder Implementations for Other Class In some cases, classes may implement rich comparison dunder methods for comparisons with a different type: @@ -85,8 +85,8 @@ reveal_type(A() >= B()) # revealed: set ## Reflected Comparisons Fallback to the right-hand side’s comparison methods occurs when the left-hand -side does not define them. Note: class B has its own `__eq__` and `__ne__` -methods to override those of object, but these methods will be ignored here +side does not define them. Note: class `B` has its own `__eq__` and `__ne__` +methods to override those of `object`, but these methods will be ignored here because they require a mismatched operand type. ```py @@ -119,7 +119,12 @@ class B: def __ne__(self, other: str) -> B: return B() -# TODO: should be `int` and `float`, need to check arg type and fall back to `rhs.__eq__` and `rhs.__ne__`. Because `object.__eq__` and `object.__ne__` accept `object` in typeshed, this can only happen with an invalid override of these methods, but we still support it. +# TODO: should be `int` and `float`. +# Need to check arg type and fall back to `rhs.__eq__` and `rhs.__ne__`. +# +# Because `object.__eq__` and `object.__ne__` accept `object` in typeshed, +# this can only happen with an invalid override of these methods, +# but we still support it. reveal_type(B() == A()) # revealed: B reveal_type(B() != A()) # revealed: B @@ -143,8 +148,8 @@ reveal_type(C() <= C()) # revealed: float ## Reflected Comparisons with Subclasses When subclasses override comparison methods, these overridden methods take -precedence over those in the parent class. Class B inherits from A and redefines -comparison methods to return types other than A. +precedence over those in the parent class. Class `B` inherits from `A` and +redefines comparison methods to return types other than `A`. ```py from __future__ import annotations