Skip to content

Commit

Permalink
Partially code-cover &, |, -, ^ multidict operators
Browse files Browse the repository at this point in the history
Specifically, this patch covers the cases of the dunder methods
returning `NotImplemented` and handling non-`Set` `Iterable`s.

It fully covers the `_viewbaseset_and()`, `_viewbaseset_or()`,
`_viewbaseset_sub()` and `_viewbaseset_xor()` functions in the
`multidict._multidict_base` module with functional tests.

Ref #921
PR #936

Signed-off-by: a5r0n <a5r0n@users.noreply.github.com>
Co-authored-by: a5r0n <a5r0n@users.noreply.github.com>
Co-authored-by: Sviatoslav Sydorenko <wk.cvs.github@sydorenko.org.ua>
  • Loading branch information
3 people committed Feb 1, 2024
1 parent 983411b commit 75e204c
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
9 changes: 9 additions & 0 deletions CHANGES/936.contrib.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Added test coverage for the :ref:`and <python:and>`, :ref:`or
<python:or>`, :py:obj:`sub <python:object.__sub__>`, and
:py:obj:`xor <python:object.__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`
77 changes: 77 additions & 0 deletions tests/test_multidict.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
Dict,
Iterable,
Iterator,
KeysView,
List,
Mapping,
Set,
Expand Down Expand Up @@ -391,6 +392,27 @@ 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:
d = cls([("key", "value1")])

sentinel_operation_result = object()

class RightOperand:
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:
d = cls([("key", "value1")])

assert {"key"} == d.keys() & ["key", "key2"]

def test_or(self, cls: Type[MutableMultiMapping[str]]) -> None:
d = cls([("key", "value1")])

Expand All @@ -401,6 +423,27 @@ def test_or2(self, cls: Type[MutableMultiMapping[str]]) -> None:

assert {"key", "key2"} == {"key2"} | d.keys()

def test_bitwise_or_not_implemented(
self, cls: Type[MutableMultiMapping[str]]
) -> None:
d = cls([("key", "value1")])

sentinel_operation_result = object()

class RightOperand:
def __ror__(self, other: KeysView[str]) -> object:
assert isinstance(other, KeysView)
return sentinel_operation_result

assert d.keys() | RightOperand() is sentinel_operation_result

def test_bitwise_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")])

Expand All @@ -411,6 +454,23 @@ 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")])

sentinel_operation_result = object()

class RightOperand:
def __rsub__(self, other: KeysView[str]) -> object:
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")])

assert {"key"} == d.keys() - ["key2"]

def test_xor(self, cls: Type[MutableMultiMapping[str]]) -> None:
d = cls([("key", "value1"), ("key2", "value2")])

Expand All @@ -421,6 +481,23 @@ 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")])

sentinel_operation_result = object()

class RightOperand:
def __rxor__(self, other: KeysView[str]) -> object:
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")])

assert {"key", "key3"} == d.keys() ^ ["key2", "key3"]

@pytest.mark.parametrize(
("key", "value", "expected"),
(("key2", "v", True), ("key", "value1", False)),
Expand Down

0 comments on commit 75e204c

Please sign in to comment.