From ebd8e42c9e88e6353730d59f6c73f39ea6df116d Mon Sep 17 00:00:00 2001 From: a5r0n Date: Wed, 31 Jan 2024 12:46:35 +0200 Subject: [PATCH 01/13] Add test coverage for _multidict_base.py `NotImplemented` and `Iterable` but not `Set` for `and, or, sub, xor` --- tests/test_multidict.py | 44 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/test_multidict.py b/tests/test_multidict.py index 4012a5692..4da676547 100644 --- a/tests/test_multidict.py +++ b/tests/test_multidict.py @@ -387,6 +387,17 @@ def test_and2(self, cls: Type[MutableMultiMapping[str]]) -> None: assert {"key"} == {"key", "key2"} & d.keys() + def test_and_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: + d = cls([("key", "value1")]) + + with pytest.raises(TypeError): + operator.and_(d.keys(), 1) + + def test_and_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: + d = cls([("key", "value1")]) + + assert {"key"} == d.keys() & ["key", "key2"] + def test_or(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1")]) @@ -397,6 +408,17 @@ def test_or2(self, cls: Type[MutableMultiMapping[str]]) -> None: assert {"key", "key2"} == {"key2"} | d.keys() + def test_or_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: + d = cls([("key", "value1")]) + + with pytest.raises(TypeError): + operator.or_(d.keys(), 1) + + def test_or_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: + d = cls([("key", "value1")]) + + assert {"key", "key2"} == d.keys() | ["key2"] + def test_sub(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) @@ -407,6 +429,17 @@ def test_sub2(self, cls: Type[MutableMultiMapping[str]]) -> None: assert {"key3"} == {"key", "key2", "key3"} - d.keys() + def test_sub_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: + d = cls([("key", "value1"), ("key2", "value2")]) + + with pytest.raises(TypeError): + operator.sub(d.keys(), 1) + + def test_sub_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: + d = cls([("key", "value1"), ("key2", "value2")]) + + assert {"key"} == d.keys() - ["key2"] + def test_xor(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) @@ -417,6 +450,17 @@ def test_xor2(self, cls: Type[MutableMultiMapping[str]]) -> None: assert {"key", "key3"} == {"key2", "key3"} ^ d.keys() + def test_xor_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: + d = cls([("key", "value1"), ("key2", "value2")]) + + with pytest.raises(TypeError): + operator.xor(d.keys(), 1) + + def test_xor_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: + d = cls([("key", "value1"), ("key2", "value2")]) + + assert {"key", "key3"} == d.keys() ^ ["key2", "key3"] + @pytest.mark.parametrize( ("key", "value", "expected"), (("key2", "v", True), ("key", "value1", False)), From 15133413901a1238f704ab3b6ee4a0a2f69d7369 Mon Sep 17 00:00:00 2001 From: a5r0n Date: Wed, 31 Jan 2024 12:57:55 +0200 Subject: [PATCH 02/13] Add change record --- CHANGES/936.contrib.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 CHANGES/936.contrib.rst diff --git a/CHANGES/936.contrib.rst b/CHANGES/936.contrib.rst new file mode 100644 index 000000000..6e5d60051 --- /dev/null +++ b/CHANGES/936.contrib.rst @@ -0,0 +1,2 @@ +Add test coverage for _multidict_base.py +`NotImplemented`` and `Iterable-but-not-Set` for `and, or, sub, xor` operators \ No newline at end of file From eda2283f292cc63228d7b5599e6b055c6e99f694 Mon Sep 17 00:00:00 2001 From: a5r0n <32464596+a5r0n@users.noreply.github.com> Date: Thu, 1 Feb 2024 02:39:05 +0200 Subject: [PATCH 03/13] Update CHANGES/936.contrib.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sviatoslav Sydorenko (Святослав Сидоренко) --- CHANGES/936.contrib.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES/936.contrib.rst b/CHANGES/936.contrib.rst index 6e5d60051..49b03b2a0 100644 --- a/CHANGES/936.contrib.rst +++ b/CHANGES/936.contrib.rst @@ -1,2 +1,2 @@ -Add test coverage for _multidict_base.py -`NotImplemented`` and `Iterable-but-not-Set` for `and, or, sub, xor` operators \ No newline at end of file +Added test coverage for the :ref:`and `, :ref:`or `, :ref:`sub `, and :ref:`xor ` operators in the :file:`multidict/_multidict_base.py` module. It also covers +:py:data:`NotImplemented` and ":py:class:`~typing.Iterable`-but-not-:py:class:`~Set`" cases there. \ No newline at end of file From 9c0f8e8420f9cbc209de7e1bf80cc70c26bd035b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sviatoslav=20Sydorenko=20=28=D0=A1=D0=B2=D1=8F=D1=82=D0=BE?= =?UTF-8?q?=D1=81=D0=BB=D0=B0=D0=B2=20=D0=A1=D0=B8=D0=B4=D0=BE=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE=29?= Date: Thu, 1 Feb 2024 01:44:13 +0100 Subject: [PATCH 04/13] Link `sub` & `xor` refs in changelog to the object dunders --- CHANGES/936.contrib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES/936.contrib.rst b/CHANGES/936.contrib.rst index 49b03b2a0..32454a089 100644 --- a/CHANGES/936.contrib.rst +++ b/CHANGES/936.contrib.rst @@ -1,2 +1,2 @@ -Added test coverage for the :ref:`and `, :ref:`or `, :ref:`sub `, and :ref:`xor ` operators in the :file:`multidict/_multidict_base.py` module. It also covers +Added test coverage for the :ref:`and `, :ref:`or `, :py:obj:`sub `, and :py:obj:`xor ` operators in the :file:`multidict/_multidict_base.py` module. It also covers :py:data:`NotImplemented` and ":py:class:`~typing.Iterable`-but-not-:py:class:`~Set`" cases there. \ No newline at end of file From e0d9967dd541fb59e14d5e6d3e3df66521b45e9f Mon Sep 17 00:00:00 2001 From: a5r0n Date: Thu, 1 Feb 2024 02:55:55 +0200 Subject: [PATCH 05/13] use `&,|,-,^` instead of operator functions Signed-off-by: a5r0n --- tests/test_multidict.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_multidict.py b/tests/test_multidict.py index 4da676547..2ae4c274b 100644 --- a/tests/test_multidict.py +++ b/tests/test_multidict.py @@ -390,8 +390,8 @@ def test_and2(self, cls: Type[MutableMultiMapping[str]]) -> None: def test_and_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1")]) - with pytest.raises(TypeError): - operator.and_(d.keys(), 1) + with pytest.raises(TypeError, match=r"unsupported operand type(\(s\))? for \&"): + d.keys() & 1 def test_and_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1")]) @@ -411,8 +411,8 @@ def test_or2(self, cls: Type[MutableMultiMapping[str]]) -> None: def test_or_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1")]) - with pytest.raises(TypeError): - operator.or_(d.keys(), 1) + with pytest.raises(TypeError, match=r"unsupported operand type(\(s\))? for \|"): + d.keys() | 1 def test_or_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1")]) @@ -432,8 +432,8 @@ def test_sub2(self, cls: Type[MutableMultiMapping[str]]) -> None: def test_sub_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) - with pytest.raises(TypeError): - operator.sub(d.keys(), 1) + with pytest.raises(TypeError, match=r"unsupported operand type(\(s\))? for -"): + d.keys() - 1 def test_sub_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) @@ -453,8 +453,8 @@ def test_xor2(self, cls: Type[MutableMultiMapping[str]]) -> None: def test_xor_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) - with pytest.raises(TypeError): - operator.xor(d.keys(), 1) + with pytest.raises(TypeError, match=r"unsupported operand type(\(s\))? for \^"): + d.keys() ^ 1 def test_xor_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) From 42418249f0d4b91b7ed3a1ae77283008b11a4600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sviatoslav=20Sydorenko=20=28=D0=A1=D0=B2=D1=8F=D1=82=D0=BE?= =?UTF-8?q?=D1=81=D0=BB=D0=B0=D0=B2=20=D0=A1=D0=B8=D0=B4=D0=BE=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE=29?= Date: Thu, 1 Feb 2024 01:57:50 +0100 Subject: [PATCH 06/13] Link `__xor__` from changelog --- CHANGES/936.contrib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES/936.contrib.rst b/CHANGES/936.contrib.rst index 32454a089..6460964f7 100644 --- a/CHANGES/936.contrib.rst +++ b/CHANGES/936.contrib.rst @@ -1,2 +1,2 @@ -Added test coverage for the :ref:`and `, :ref:`or `, :py:obj:`sub `, and :py:obj:`xor ` operators in the :file:`multidict/_multidict_base.py` module. It also covers +Added test coverage for the :ref:`and `, :ref:`or `, :py:obj:`sub `, and :py:obj:`xor ` operators in the :file:`multidict/_multidict_base.py` module. It also covers :py:data:`NotImplemented` and ":py:class:`~typing.Iterable`-but-not-:py:class:`~Set`" cases there. \ No newline at end of file From e8157ec7eed5680e995b5ce1880e6b8ab4450ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sviatoslav=20Sydorenko=20=28=D0=A1=D0=B2=D1=8F=D1=82=D0=BE?= =?UTF-8?q?=D1=81=D0=BB=D0=B0=D0=B2=20=D0=A1=D0=B8=D0=B4=D0=BE=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE=29?= Date: Thu, 1 Feb 2024 02:03:17 +0100 Subject: [PATCH 07/13] Use full ref to `typing.Set` @ changelog --- CHANGES/936.contrib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES/936.contrib.rst b/CHANGES/936.contrib.rst index 6460964f7..0af9a46b9 100644 --- a/CHANGES/936.contrib.rst +++ b/CHANGES/936.contrib.rst @@ -1,2 +1,2 @@ Added test coverage for the :ref:`and `, :ref:`or `, :py:obj:`sub `, and :py:obj:`xor ` operators in the :file:`multidict/_multidict_base.py` module. It also covers -:py:data:`NotImplemented` and ":py:class:`~typing.Iterable`-but-not-:py:class:`~Set`" cases there. \ No newline at end of file +:py:data:`NotImplemented` and ":py:class:`~typing.Iterable`-but-not-:py:class:`~typing.Set`" cases there. \ No newline at end of file From 707e2ef100030439ad4ef7566abe3c0232323ab9 Mon Sep 17 00:00:00 2001 From: a5r0n Date: Thu, 1 Feb 2024 03:34:09 +0200 Subject: [PATCH 08/13] use right operand to check NotImplemnted branch Signed-off-by: a5r0n --- tests/test_multidict.py | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/tests/test_multidict.py b/tests/test_multidict.py index 2ae4c274b..b0a2008a8 100644 --- a/tests/test_multidict.py +++ b/tests/test_multidict.py @@ -12,6 +12,7 @@ Dict, Iterable, Iterator, + KeysView, List, Mapping, Set, @@ -390,8 +391,14 @@ def test_and2(self, cls: Type[MutableMultiMapping[str]]) -> None: def test_and_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1")]) - with pytest.raises(TypeError, match=r"unsupported operand type(\(s\))? for \&"): - d.keys() & 1 + sentinel_operation_result = object() + + class RightOperand: + def __rand__(self, other): + assert isinstance(other, KeysView) + return sentinel_operation_result + + assert d.keys() & RightOperand() is sentinel_operation_result def test_and_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1")]) @@ -411,8 +418,14 @@ def test_or2(self, cls: Type[MutableMultiMapping[str]]) -> None: def test_or_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1")]) - with pytest.raises(TypeError, match=r"unsupported operand type(\(s\))? for \|"): - d.keys() | 1 + sentinel_operation_result = object() + + class RightOperand: + def __ror__(self, other): + assert isinstance(other, KeysView) + return sentinel_operation_result + + assert d.keys() | RightOperand() is sentinel_operation_result def test_or_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1")]) @@ -432,8 +445,14 @@ def test_sub2(self, cls: Type[MutableMultiMapping[str]]) -> None: def test_sub_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) - with pytest.raises(TypeError, match=r"unsupported operand type(\(s\))? for -"): - d.keys() - 1 + sentinel_operation_result = object() + + class RightOperand: + def __rsub__(self, other): + assert isinstance(other, KeysView) + return sentinel_operation_result + + assert d.keys() - RightOperand() is sentinel_operation_result def test_sub_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) @@ -453,8 +472,14 @@ def test_xor2(self, cls: Type[MutableMultiMapping[str]]) -> None: def test_xor_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) - with pytest.raises(TypeError, match=r"unsupported operand type(\(s\))? for \^"): - d.keys() ^ 1 + sentinel_operation_result = object() + + class RightOperand: + def __rxor__(self, other): + assert isinstance(other, KeysView) + return sentinel_operation_result + + assert d.keys() ^ RightOperand() is sentinel_operation_result def test_xor_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) From 5b74f84094162c189402ce54d14f059f07a38f06 Mon Sep 17 00:00:00 2001 From: a5r0n Date: Thu, 1 Feb 2024 04:09:56 +0200 Subject: [PATCH 09/13] should be bitwise_or Signed-off-by: a5r0n --- tests/test_multidict.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/test_multidict.py b/tests/test_multidict.py index b0a2008a8..99579c24e 100644 --- a/tests/test_multidict.py +++ b/tests/test_multidict.py @@ -415,7 +415,9 @@ def test_or2(self, cls: Type[MutableMultiMapping[str]]) -> None: assert {"key", "key2"} == {"key2"} | d.keys() - def test_or_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_bitwise_or_not_implemented( + self, cls: Type[MutableMultiMapping[str]] + ) -> None: d = cls([("key", "value1")]) sentinel_operation_result = object() @@ -427,7 +429,9 @@ def __ror__(self, other): assert d.keys() | RightOperand() is sentinel_operation_result - def test_or_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_bitwise_or_iterable_not_set( + self, cls: Type[MutableMultiMapping[str]] + ) -> None: d = cls([("key", "value1")]) assert {"key", "key2"} == d.keys() | ["key2"] From e2cf661918a0cec5e9fbe9f3a11b501038303498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sviatoslav=20Sydorenko=20=28=D0=A1=D0=B2=D1=8F=D1=82=D0=BE?= =?UTF-8?q?=D1=81=D0=BB=D0=B0=D0=B2=20=D0=A1=D0=B8=D0=B4=D0=BE=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE=29?= Date: Thu, 1 Feb 2024 03:17:43 +0100 Subject: [PATCH 10/13] Wrap the change note adding a byline --- CHANGES/936.contrib.rst | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGES/936.contrib.rst b/CHANGES/936.contrib.rst index 0af9a46b9..832f09d1e 100644 --- a/CHANGES/936.contrib.rst +++ b/CHANGES/936.contrib.rst @@ -1,2 +1,9 @@ -Added test coverage for the :ref:`and `, :ref:`or `, :py:obj:`sub `, and :py:obj:`xor ` operators in the :file:`multidict/_multidict_base.py` module. It also covers -:py:data:`NotImplemented` and ":py:class:`~typing.Iterable`-but-not-:py:class:`~typing.Set`" cases there. \ No newline at end of file +Added test coverage for the :ref:`and `, :ref:`or +`, :py:obj:`sub `, and +:py:obj:`xor ` operators in the +:file:`multidict/_multidict_base.py` module. It also covers +:py:data:`NotImplemented` and +":py:class:`~typing.Iterable`-but-not-:py:class:`~typing.Set`" +cases there. + +-- by :user:`a5r0n` \ No newline at end of file From 4831057141b127aa743d4bdc4953dfa6e5f5a37f Mon Sep 17 00:00:00 2001 From: a5r0n <32464596+a5r0n@users.noreply.github.com> Date: Thu, 1 Feb 2024 04:25:23 +0200 Subject: [PATCH 11/13] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sviatoslav Sydorenko (Святослав Сидоренко) --- tests/test_multidict.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_multidict.py b/tests/test_multidict.py index 99579c24e..ff49061ec 100644 --- a/tests/test_multidict.py +++ b/tests/test_multidict.py @@ -388,7 +388,7 @@ def test_and2(self, cls: Type[MutableMultiMapping[str]]) -> None: assert {"key"} == {"key", "key2"} & d.keys() - def test_and_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_bitwise_and_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1")]) sentinel_operation_result = object() @@ -400,7 +400,7 @@ def __rand__(self, other): assert d.keys() & RightOperand() is sentinel_operation_result - def test_and_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_bitwise_and_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: d = cls([("key", "value1")]) assert {"key"} == d.keys() & ["key", "key2"] From 8dc236a8fbfc6ee32e0480d343198032c8563c4f Mon Sep 17 00:00:00 2001 From: a5r0n Date: Thu, 1 Feb 2024 04:28:20 +0200 Subject: [PATCH 12/13] type annotations for RightOperand methods Signed-off-by: a5r0n --- tests/test_multidict.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_multidict.py b/tests/test_multidict.py index ff49061ec..24af8f093 100644 --- a/tests/test_multidict.py +++ b/tests/test_multidict.py @@ -394,7 +394,7 @@ def test_bitwise_and_not_implemented(self, cls: Type[MutableMultiMapping[str]]) sentinel_operation_result = object() class RightOperand: - def __rand__(self, other): + def __rand__(self, other: KeysView) -> object: assert isinstance(other, KeysView) return sentinel_operation_result @@ -423,7 +423,7 @@ def test_bitwise_or_not_implemented( sentinel_operation_result = object() class RightOperand: - def __ror__(self, other): + def __ror__(self, other: KeysView) -> object: assert isinstance(other, KeysView) return sentinel_operation_result @@ -452,7 +452,7 @@ def test_sub_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: sentinel_operation_result = object() class RightOperand: - def __rsub__(self, other): + def __rsub__(self, other: KeysView) -> object: assert isinstance(other, KeysView) return sentinel_operation_result @@ -479,7 +479,7 @@ def test_xor_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: sentinel_operation_result = object() class RightOperand: - def __rxor__(self, other): + def __rxor__(self, other: KeysView) -> object: assert isinstance(other, KeysView) return sentinel_operation_result From a96cbe9fd16e9fd336e2dc5bf4909dc330b5f625 Mon Sep 17 00:00:00 2001 From: a5r0n Date: Thu, 1 Feb 2024 04:33:30 +0200 Subject: [PATCH 13/13] type annotations args for RightOperand methods Signed-off-by: a5r0n --- tests/test_multidict.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/test_multidict.py b/tests/test_multidict.py index 24af8f093..0ce8c0373 100644 --- a/tests/test_multidict.py +++ b/tests/test_multidict.py @@ -388,19 +388,23 @@ def test_and2(self, cls: Type[MutableMultiMapping[str]]) -> None: assert {"key"} == {"key", "key2"} & d.keys() - def test_bitwise_and_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_bitwise_and_not_implemented( + self, cls: Type[MutableMultiMapping[str]] + ) -> None: d = cls([("key", "value1")]) sentinel_operation_result = object() class RightOperand: - def __rand__(self, other: KeysView) -> object: + def __rand__(self, other: KeysView[str]) -> object: assert isinstance(other, KeysView) return sentinel_operation_result assert d.keys() & RightOperand() is sentinel_operation_result - def test_bitwise_and_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_bitwise_and_iterable_not_set( + self, cls: Type[MutableMultiMapping[str]] + ) -> None: d = cls([("key", "value1")]) assert {"key"} == d.keys() & ["key", "key2"] @@ -423,7 +427,7 @@ def test_bitwise_or_not_implemented( sentinel_operation_result = object() class RightOperand: - def __ror__(self, other: KeysView) -> object: + def __ror__(self, other: KeysView[str]) -> object: assert isinstance(other, KeysView) return sentinel_operation_result @@ -452,7 +456,7 @@ def test_sub_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: sentinel_operation_result = object() class RightOperand: - def __rsub__(self, other: KeysView) -> object: + def __rsub__(self, other: KeysView[str]) -> object: assert isinstance(other, KeysView) return sentinel_operation_result @@ -479,7 +483,7 @@ def test_xor_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: sentinel_operation_result = object() class RightOperand: - def __rxor__(self, other: KeysView) -> object: + def __rxor__(self, other: KeysView[str]) -> object: assert isinstance(other, KeysView) return sentinel_operation_result