diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2025-04-01 10:18:34 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2025-04-01 10:29:52 +0300 |
commit | bf4197b54ff69b2ec6ad452fa090c64d303e60f6 (patch) | |
tree | 412e559a326b0299697b470bd5e954fc344f2631 /contrib/python/multidict/tests | |
parent | 16a607d57a2bed8443afafe90913420ebc9c0c38 (diff) | |
download | ydb-bf4197b54ff69b2ec6ad452fa090c64d303e60f6.tar.gz |
Intermediate changes
commit_hash:d293c67803538ae096ac64ceb5f8db15221724d3
Diffstat (limited to 'contrib/python/multidict/tests')
-rw-r--r-- | contrib/python/multidict/tests/conftest.py | 68 | ||||
-rw-r--r-- | contrib/python/multidict/tests/gen_pickles.py | 8 | ||||
-rw-r--r-- | contrib/python/multidict/tests/test_abc.py | 86 | ||||
-rw-r--r-- | contrib/python/multidict/tests/test_copy.py | 16 | ||||
-rw-r--r-- | contrib/python/multidict/tests/test_guard.py | 10 | ||||
-rw-r--r-- | contrib/python/multidict/tests/test_istr.py | 2 | ||||
-rw-r--r-- | contrib/python/multidict/tests/test_multidict.py | 252 | ||||
-rw-r--r-- | contrib/python/multidict/tests/test_multidict_benchmarks.py | 391 | ||||
-rw-r--r-- | contrib/python/multidict/tests/test_mutable_multidict.py | 124 | ||||
-rw-r--r-- | contrib/python/multidict/tests/test_pickle.py | 21 | ||||
-rw-r--r-- | contrib/python/multidict/tests/test_types.py | 52 | ||||
-rw-r--r-- | contrib/python/multidict/tests/test_update.py | 44 | ||||
-rw-r--r-- | contrib/python/multidict/tests/test_version.py | 91 |
13 files changed, 755 insertions, 410 deletions
diff --git a/contrib/python/multidict/tests/conftest.py b/contrib/python/multidict/tests/conftest.py index 0d003950cd7..a37f58f2d1f 100644 --- a/contrib/python/multidict/tests/conftest.py +++ b/contrib/python/multidict/tests/conftest.py @@ -3,26 +3,22 @@ from __future__ import annotations import argparse import pickle from dataclasses import dataclass +from functools import cached_property from importlib import import_module -from sys import version_info as _version_info from types import ModuleType -from typing import Callable, Type - -try: - from functools import cached_property # Python 3.8+ -except ImportError: - from functools import lru_cache as _lru_cache - - def cached_property(func): - return property(_lru_cache()(func)) - +from typing import Callable, Type, Union import pytest -from multidict import MultiMapping, MutableMultiMapping +from multidict import ( + CIMultiDict, + MultiDict, + MultiDictProxy, + MultiMapping, + MutableMultiMapping, +) C_EXT_MARK = pytest.mark.c_extension -PY_38_AND_BELOW = _version_info < (3, 9) @dataclass(frozen=True) @@ -51,7 +47,7 @@ class MultidictImplementation: importable_module = "_multidict_py" if self.is_pure_python else "_multidict" return import_module(f"multidict.{importable_module}") - def __str__(self): + def __str__(self) -> str: """Render the implementation facade instance as a string.""" return f"{self.tag}-module" @@ -69,7 +65,7 @@ class MultidictImplementation: ) def multidict_implementation(request: pytest.FixtureRequest) -> MultidictImplementation: """Return a multidict variant facade.""" - return request.param + return request.param # type: ignore[no-any-return] @pytest.fixture(scope="session") @@ -87,7 +83,7 @@ def multidict_module( ) def any_multidict_class_name(request: pytest.FixtureRequest) -> str: """Return a class name of a mutable multidict implementation.""" - return request.param + return request.param # type: ignore[no-any-return] @pytest.fixture(scope="session") @@ -96,29 +92,29 @@ def any_multidict_class( multidict_module: ModuleType, ) -> Type[MutableMultiMapping[str]]: """Return a class object of a mutable multidict implementation.""" - return getattr(multidict_module, any_multidict_class_name) + return getattr(multidict_module, any_multidict_class_name) # type: ignore[no-any-return] @pytest.fixture(scope="session") def case_sensitive_multidict_class( multidict_module: ModuleType, -) -> Type[MutableMultiMapping[str]]: +) -> Type[MultiDict[str]]: """Return a case-sensitive mutable multidict class.""" - return multidict_module.MultiDict + return multidict_module.MultiDict # type: ignore[no-any-return] @pytest.fixture(scope="session") def case_insensitive_multidict_class( multidict_module: ModuleType, -) -> Type[MutableMultiMapping[str]]: +) -> Type[CIMultiDict[str]]: """Return a case-insensitive mutable multidict class.""" - return multidict_module.CIMultiDict + return multidict_module.CIMultiDict # type: ignore[no-any-return] @pytest.fixture(scope="session") def case_insensitive_str_class(multidict_module: ModuleType) -> Type[str]: """Return a case-insensitive string class.""" - return multidict_module.istr + return multidict_module.istr # type: ignore[no-any-return] @pytest.fixture(scope="session") @@ -133,7 +129,7 @@ def any_multidict_proxy_class( multidict_module: ModuleType, ) -> Type[MultiMapping[str]]: """Return an immutable multidict implementation class object.""" - return getattr(multidict_module, any_multidict_proxy_class_name) + return getattr(multidict_module, any_multidict_proxy_class_name) # type: ignore[no-any-return] @pytest.fixture(scope="session") @@ -141,7 +137,7 @@ def case_sensitive_multidict_proxy_class( multidict_module: ModuleType, ) -> Type[MutableMultiMapping[str]]: """Return a case-sensitive immutable multidict class.""" - return multidict_module.MultiDictProxy + return multidict_module.MultiDictProxy # type: ignore[no-any-return] @pytest.fixture(scope="session") @@ -149,13 +145,15 @@ def case_insensitive_multidict_proxy_class( multidict_module: ModuleType, ) -> Type[MutableMultiMapping[str]]: """Return a case-insensitive immutable multidict class.""" - return multidict_module.CIMultiDictProxy + return multidict_module.CIMultiDictProxy # type: ignore[no-any-return] @pytest.fixture(scope="session") -def multidict_getversion_callable(multidict_module: ModuleType) -> Callable: +def multidict_getversion_callable( + multidict_module: ModuleType, +) -> Callable[[Union[MultiDict[object], MultiDictProxy[object]]], int]: """Return a ``getversion()`` function for current implementation.""" - return multidict_module.getversion + return multidict_module.getversion # type: ignore[no-any-return] def pytest_addoption( @@ -171,20 +169,12 @@ def pytest_addoption( parser.addoption( "--c-extensions", # disabled with `--no-c-extensions` - action="store_true" if PY_38_AND_BELOW else argparse.BooleanOptionalAction, + action=argparse.BooleanOptionalAction, default=True, dest="c_extensions", help="Test C-extensions (on by default)", ) - if PY_38_AND_BELOW: - parser.addoption( - "--no-c-extensions", - action="store_false", - dest="c_extensions", - help="Skip testing C-extensions (on by default)", - ) - def pytest_collection_modifyitems( session: pytest.Session, @@ -197,8 +187,8 @@ def pytest_collection_modifyitems( if test_c_extensions: return - selected_tests = [] - deselected_tests = [] + selected_tests: list[pytest.Item] = [] + deselected_tests: list[pytest.Item] = [] for item in items: c_ext = item.get_closest_marker(C_EXT_MARK.name) is not None @@ -218,7 +208,7 @@ def pytest_configure(config: pytest.Config) -> None: ) -def pytest_generate_tests(metafunc): +def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: if "pickle_protocol" in metafunc.fixturenames: metafunc.parametrize( "pickle_protocol", list(range(pickle.HIGHEST_PROTOCOL + 1)), scope="session" diff --git a/contrib/python/multidict/tests/gen_pickles.py b/contrib/python/multidict/tests/gen_pickles.py index 4e0d268bedd..72f41b7565f 100644 --- a/contrib/python/multidict/tests/gen_pickles.py +++ b/contrib/python/multidict/tests/gen_pickles.py @@ -1,18 +1,22 @@ import pickle from importlib import import_module from pathlib import Path +from typing import Union + +from multidict import CIMultiDict, MultiDict TESTS_DIR = Path(__file__).parent.resolve() +_MD_Classes = Union[type[MultiDict[int]], type[CIMultiDict[int]]] -def write(tag, cls, proto): +def write(tag: str, cls: _MD_Classes, proto: int) -> None: d = cls([("a", 1), ("a", 2)]) file_basename = f"{cls.__name__.lower()}-{tag}" with (TESTS_DIR / f"{file_basename}.pickle.{proto}").open("wb") as f: pickle.dump(d, f, proto) -def generate(): +def generate() -> None: _impl_map = { "c-extension": "_multidict", "pure-python": "_multidict_py", diff --git a/contrib/python/multidict/tests/test_abc.py b/contrib/python/multidict/tests/test_abc.py index e18ad83f820..611d0fa8c35 100644 --- a/contrib/python/multidict/tests/test_abc.py +++ b/contrib/python/multidict/tests/test_abc.py @@ -1,94 +1,32 @@ from collections.abc import Mapping, MutableMapping -import pytest +from multidict import ( + MultiDict, + MultiDictProxy, + MultiMapping, + MutableMultiMapping, +) -from multidict import MultiMapping, MutableMultiMapping - -def test_abc_inheritance(): +def test_abc_inheritance() -> None: assert issubclass(MultiMapping, Mapping) assert not issubclass(MultiMapping, MutableMapping) assert issubclass(MutableMultiMapping, Mapping) assert issubclass(MutableMultiMapping, MutableMapping) -class A(MultiMapping): - def __getitem__(self, key): - pass - - def __iter__(self): - pass - - def __len__(self): - pass - - def getall(self, key, default=None): - super().getall(key, default) - - def getone(self, key, default=None): - super().getone(key, default) - - -def test_abc_getall(): - with pytest.raises(KeyError): - A().getall("key") - - -def test_abc_getone(): - with pytest.raises(KeyError): - A().getone("key") - - -class B(A, MutableMultiMapping): - def __setitem__(self, key, value): - pass - - def __delitem__(self, key): - pass - - def add(self, key, value): - super().add(key, value) - - def extend(self, *args, **kwargs): - super().extend(*args, **kwargs) - - def popall(self, key, default=None): - super().popall(key, default) - - def popone(self, key, default=None): - super().popone(key, default) - - -def test_abc_add(): - with pytest.raises(NotImplementedError): - B().add("key", "val") - - -def test_abc_extend(): - with pytest.raises(NotImplementedError): - B().extend() - - -def test_abc_popone(): - with pytest.raises(KeyError): - B().popone("key") - - -def test_abc_popall(): - with pytest.raises(KeyError): - B().popall("key") - - -def test_multidict_inheritance(any_multidict_class): +def test_multidict_inheritance(any_multidict_class: type[MultiDict[str]]) -> None: assert issubclass(any_multidict_class, MultiMapping) assert issubclass(any_multidict_class, MutableMultiMapping) -def test_proxy_inheritance(any_multidict_proxy_class): +def test_proxy_inheritance( + any_multidict_proxy_class: type[MultiDictProxy[str]], +) -> None: assert issubclass(any_multidict_proxy_class, MultiMapping) assert not issubclass(any_multidict_proxy_class, MutableMultiMapping) -def test_generic_type_in_runtime(): +def test_generic_type_in_runtime() -> None: MultiMapping[str] MutableMultiMapping[str] diff --git a/contrib/python/multidict/tests/test_copy.py b/contrib/python/multidict/tests/test_copy.py index cd926cdc1d3..deff64db372 100644 --- a/contrib/python/multidict/tests/test_copy.py +++ b/contrib/python/multidict/tests/test_copy.py @@ -1,7 +1,13 @@ import copy +from typing import Union +from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy -def test_copy(any_multidict_class): +_MD_Classes = Union[type[MultiDict[int]], type[CIMultiDict[int]]] +_MDP_Classes = Union[type[MultiDictProxy[int]], type[CIMultiDictProxy[int]]] + + +def test_copy(any_multidict_class: _MD_Classes) -> None: d = any_multidict_class() d["foo"] = 6 d2 = d.copy() @@ -10,7 +16,9 @@ def test_copy(any_multidict_class): assert d2["foo"] == 7 -def test_copy_proxy(any_multidict_class, any_multidict_proxy_class): +def test_copy_proxy( + any_multidict_class: _MD_Classes, any_multidict_proxy_class: _MDP_Classes +) -> None: d = any_multidict_class() d["foo"] = 6 p = any_multidict_proxy_class(d) @@ -21,7 +29,7 @@ def test_copy_proxy(any_multidict_class, any_multidict_proxy_class): assert d2["foo"] == 7 -def test_copy_std_copy(any_multidict_class): +def test_copy_std_copy(any_multidict_class: _MD_Classes) -> None: d = any_multidict_class() d["foo"] = 6 d2 = copy.copy(d) @@ -30,7 +38,7 @@ def test_copy_std_copy(any_multidict_class): assert d2["foo"] == 7 -def test_ci_multidict_clone(any_multidict_class): +def test_ci_multidict_clone(any_multidict_class: _MD_Classes) -> None: d = any_multidict_class(foo=6) d2 = any_multidict_class(d) d2["foo"] = 7 diff --git a/contrib/python/multidict/tests/test_guard.py b/contrib/python/multidict/tests/test_guard.py index 225da67c8d2..c877fbf803c 100644 --- a/contrib/python/multidict/tests/test_guard.py +++ b/contrib/python/multidict/tests/test_guard.py @@ -1,12 +1,10 @@ -from typing import Type - import pytest -from multidict import MultiMapping +from multidict import MultiDict def test_guard_items( - case_sensitive_multidict_class: Type[MultiMapping[str]], + case_sensitive_multidict_class: type[MultiDict[str]], ) -> None: md = case_sensitive_multidict_class({"a": "b"}) it = iter(md.items()) @@ -16,7 +14,7 @@ def test_guard_items( def test_guard_keys( - case_sensitive_multidict_class: Type[MultiMapping[str]], + case_sensitive_multidict_class: type[MultiDict[str]], ) -> None: md = case_sensitive_multidict_class({"a": "b"}) it = iter(md.keys()) @@ -26,7 +24,7 @@ def test_guard_keys( def test_guard_values( - case_sensitive_multidict_class: Type[MultiMapping[str]], + case_sensitive_multidict_class: type[MultiDict[str]], ) -> None: md = case_sensitive_multidict_class({"a": "b"}) it = iter(md.values()) diff --git a/contrib/python/multidict/tests/test_istr.py b/contrib/python/multidict/tests/test_istr.py index 1918153532b..101f5fe8e5d 100644 --- a/contrib/python/multidict/tests/test_istr.py +++ b/contrib/python/multidict/tests/test_istr.py @@ -71,4 +71,4 @@ def test_leak(create_istrs: Callable[[], None]) -> None: gc.collect() cnt2 = len(gc.get_objects()) - assert abs(cnt - cnt2) < 10 # on PyPy these numbers are not equal + assert abs(cnt - cnt2) < 50 # on PyPy these numbers are not equal diff --git a/contrib/python/multidict/tests/test_multidict.py b/contrib/python/multidict/tests/test_multidict.py index bcfa699c15b..d144130a41f 100644 --- a/contrib/python/multidict/tests/test_multidict.py +++ b/contrib/python/multidict/tests/test_multidict.py @@ -5,27 +5,20 @@ import operator import sys import weakref from collections import deque -from collections.abc import Mapping +from collections.abc import Callable, Iterable, Iterator, KeysView, Mapping from types import ModuleType -from typing import ( - Callable, - Dict, - Iterable, - Iterator, - KeysView, - List, - Mapping, - Set, - Tuple, - Type, - Union, - cast, -) +from typing import Union, cast import pytest import multidict -from multidict import CIMultiDict, MultiDict, MultiMapping, MutableMultiMapping +from multidict import ( + CIMultiDict, + MultiDict, + MultiDictProxy, + MultiMapping, + MutableMultiMapping, +) def chained_callable( @@ -71,7 +64,7 @@ def cls( # type: ignore[misc] def test_exposed_names(any_multidict_class_name: str) -> None: - assert any_multidict_class_name in multidict.__all__ # type: ignore[attr-defined] + assert any_multidict_class_name in multidict.__all__ @pytest.mark.parametrize( @@ -86,8 +79,8 @@ def test_exposed_names(any_multidict_class_name: str) -> None: indirect=["cls"], ) def test__iter__types( - cls: Type[MultiDict[Union[str, int]]], - key_cls: Type[object], + cls: type[MultiDict[Union[str, int]]], + key_cls: type[str], ) -> None: d = cls([("key", "one"), ("key2", "two"), ("key", 3)]) for i in d: @@ -95,26 +88,26 @@ def test__iter__types( def test_proxy_copy( - any_multidict_class: Type[MutableMultiMapping[str]], - any_multidict_proxy_class: Type[MultiMapping[str]], + any_multidict_class: type[MultiDict[str]], + any_multidict_proxy_class: type[MultiDictProxy[str]], ) -> None: d1 = any_multidict_class(key="value", a="b") p1 = any_multidict_proxy_class(d1) - d2 = p1.copy() # type: ignore[attr-defined] + d2 = p1.copy() assert d1 == d2 assert d1 is not d2 def test_multidict_subclassing( - any_multidict_class: Type[MutableMultiMapping[str]], + any_multidict_class: type[MultiDict[str]], ) -> None: class DummyMultidict(any_multidict_class): # type: ignore[valid-type,misc] pass def test_multidict_proxy_subclassing( - any_multidict_proxy_class: Type[MultiMapping[str]], + any_multidict_proxy_class: type[MultiDictProxy[str]], ) -> None: class DummyMultidictProxy( any_multidict_proxy_class, # type: ignore[valid-type,misc] @@ -123,7 +116,7 @@ def test_multidict_proxy_subclassing( class BaseMultiDictTest: - def test_instantiate__empty(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_instantiate__empty(self, cls: type[MutableMultiMapping[str]]) -> None: d = cls() empty: Mapping[str, str] = {} assert d == empty @@ -133,14 +126,14 @@ class BaseMultiDictTest: assert list(d.items()) == [] assert cls() != list() # type: ignore[comparison-overlap] - with pytest.raises(TypeError, match=r"(2 given)"): + with pytest.raises(TypeError, match=r"3 were given"): cls(("key1", "value1"), ("key2", "value2")) # type: ignore[call-arg] # noqa: E501 @pytest.mark.parametrize("arg0", ([("key", "value1")], {"key": "value1"})) def test_instantiate__from_arg0( self, - cls: Type[MutableMultiMapping[str]], - arg0: Union[List[Tuple[str, str]], Dict[str, str]], + cls: type[MultiDict[str]], + arg0: Union[list[tuple[str, str]], dict[str, str]], ) -> None: d = cls(arg0) @@ -152,7 +145,7 @@ class BaseMultiDictTest: def test_instantiate__with_kwargs( self, - cls: Type[MutableMultiMapping[str]], + cls: type[MultiDict[str]], ) -> None: d = cls([("key", "value1")], key2="value2") @@ -163,7 +156,7 @@ class BaseMultiDictTest: assert sorted(d.items()) == [("key", "value1"), ("key2", "value2")] def test_instantiate__from_generator( - self, cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]] + self, cls: Union[type[MultiDict[int]], type[CIMultiDict[int]]] ) -> None: d = cls((str(i), i) for i in range(2)) @@ -175,7 +168,7 @@ class BaseMultiDictTest: def test_instantiate__from_list_of_lists( self, - cls: Type[MutableMultiMapping[str]], + cls: type[MutableMultiMapping[str]], ) -> None: # Should work at runtime, but won't type check. d = cls([["key", "value1"]]) # type: ignore[call-arg] @@ -183,7 +176,7 @@ class BaseMultiDictTest: def test_instantiate__from_list_of_custom_pairs( self, - cls: Type[MutableMultiMapping[str]], + cls: type[MultiDict[str]], ) -> None: class Pair: def __len__(self) -> int: @@ -193,10 +186,10 @@ class BaseMultiDictTest: return ("key", "value1")[pos] # Works at runtime, but won't type check. - d = cls([Pair()]) + d = cls([Pair()]) # type: ignore[list-item] assert d == {"key": "value1"} - def test_getone(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_getone(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")], key="value2") assert d.getone("key") == "value1" @@ -210,25 +203,42 @@ class BaseMultiDictTest: assert d.getone("key2", "default") == "default" - def test_call_with_kwargs(self, cls: Type[MultiDict[str]]) -> None: + def test_call_with_kwargs(self, cls: type[MultiDict[str]]) -> None: d = cls([("present", "value")]) assert d.getall(default="missing", key="notfound") == "missing" def test__iter__( self, cls: Union[ - Type[MultiDict[Union[str, int]]], - Type[CIMultiDict[Union[str, int]]], + type[MultiDict[Union[str, int]]], + type[CIMultiDict[Union[str, int]]], ], ) -> None: d = cls([("key", "one"), ("key2", "two"), ("key", 3)]) assert list(d) == ["key", "key2", "key"] + def test__contains( + self, + cls: Union[ + type[MultiDict[Union[str, int]]], + type[CIMultiDict[Union[str, int]]], + ], + ) -> None: + d = cls([("key", "one"), ("key2", "two"), ("key", 3)]) + + assert list(d) == ["key", "key2", "key"] + + assert "key" in d + assert "key2" in d + + assert "foo" not in d + assert 42 not in d # type: ignore[comparison-overlap] + def test_keys__contains( self, cls: Union[ - Type[MultiDict[Union[str, int]]], - Type[CIMultiDict[Union[str, int]]], + type[MultiDict[Union[str, int]]], + type[CIMultiDict[Union[str, int]]], ], ) -> None: d = cls([("key", "one"), ("key2", "two"), ("key", 3)]) @@ -239,12 +249,13 @@ class BaseMultiDictTest: assert "key2" in d.keys() assert "foo" not in d.keys() + assert 42 not in d.keys() # type: ignore[comparison-overlap] def test_values__contains( self, cls: Union[ - Type[MultiDict[Union[str, int]]], - Type[CIMultiDict[Union[str, int]]], + type[MultiDict[Union[str, int]]], + type[CIMultiDict[Union[str, int]]], ], ) -> None: d = cls([("key", "one"), ("key", "two"), ("key", 3)]) @@ -260,8 +271,8 @@ class BaseMultiDictTest: def test_items__contains( self, cls: Union[ - Type[MultiDict[Union[str, int]]], - Type[CIMultiDict[Union[str, int]]], + type[MultiDict[Union[str, int]]], + type[CIMultiDict[Union[str, int]]], ], ) -> None: d = cls([("key", "one"), ("key", "two"), ("key", 3)]) @@ -273,15 +284,17 @@ class BaseMultiDictTest: assert ("key", 3) in d.items() assert ("foo", "bar") not in d.items() + assert (42, 3) not in d.items() # type: ignore[comparison-overlap] + assert 42 not in d.items() # type: ignore[comparison-overlap] def test_cannot_create_from_unaccepted( self, - cls: Type[MutableMultiMapping[str]], + cls: type[MutableMultiMapping[str]], ) -> None: with pytest.raises(TypeError): cls([(1, 2, 3)]) # type: ignore[call-arg] - def test_keys_is_set_less(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_keys_is_set_less(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) assert d.keys() < {"key", "key2"} @@ -297,8 +310,8 @@ class BaseMultiDictTest: ) def test_keys_is_set_less_equal( self, - cls: Type[MutableMultiMapping[str]], - contents: List[Tuple[str, str]], + cls: type[MultiDict[str]], + contents: list[tuple[str, str]], expected: bool, ) -> None: d = cls(contents) @@ -306,12 +319,17 @@ class BaseMultiDictTest: result = d.keys() <= {"key", "key2"} assert result is expected - def test_keys_is_set_equal(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_keys_is_set_equal(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) assert d.keys() == {"key"} - def test_keys_is_set_greater(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_items_is_set_equal(self, cls: type[MultiDict[str]]) -> None: + d = cls([("key", "value1")]) + + assert d.items() == {("key", "value1")} + + def test_keys_is_set_greater(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) assert d.keys() > {"key"} @@ -326,16 +344,14 @@ class BaseMultiDictTest: ), ) def test_keys_is_set_greater_equal( - self, cls: Type[MutableMultiMapping[str]], set_: Set[str], expected: bool + self, cls: type[MultiDict[str]], set_: set[str], expected: bool ) -> None: d = cls([("key", "value1"), ("key2", "value2")]) result = d.keys() >= set_ assert result is expected - def test_keys_less_than_not_implemented( - self, cls: Type[MutableMultiMapping[str]] - ) -> None: + def test_keys_less_than_not_implemented(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) sentinel_operation_result = object() @@ -348,7 +364,7 @@ class BaseMultiDictTest: assert (d.keys() < RightOperand()) is sentinel_operation_result def test_keys_less_than_or_equal_not_implemented( - self, cls: Type[MutableMultiMapping[str]] + self, cls: type[MultiDict[str]] ) -> None: d = cls([("key", "value1")]) @@ -361,9 +377,7 @@ class BaseMultiDictTest: assert (d.keys() <= RightOperand()) is sentinel_operation_result - def test_keys_greater_than_not_implemented( - self, cls: Type[MutableMultiMapping[str]] - ) -> None: + def test_keys_greater_than_not_implemented(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) sentinel_operation_result = object() @@ -376,7 +390,7 @@ class BaseMultiDictTest: assert (d.keys() > RightOperand()) is sentinel_operation_result def test_keys_greater_than_or_equal_not_implemented( - self, cls: Type[MutableMultiMapping[str]] + self, cls: type[MultiDict[str]] ) -> None: d = cls([("key", "value1")]) @@ -389,30 +403,28 @@ class BaseMultiDictTest: assert (d.keys() >= RightOperand()) is sentinel_operation_result - def test_keys_is_set_not_equal(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_keys_is_set_not_equal(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) assert d.keys() != {"key2"} - def test_keys_not_equal_unrelated_type( - self, cls: Type[MutableMultiMapping[str]] - ) -> None: + def test_keys_not_equal_unrelated_type(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) - assert d.keys() != "other" + assert d.keys() != "other" # type: ignore[comparison-overlap] - def test_eq(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_eq(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) assert {"key": "value1"} == d - def test_eq2(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_eq2(self, cls: type[MultiDict[str]]) -> None: d1 = cls([("key", "value1")]) d2 = cls([("key2", "value1")]) assert d1 != d2 - def test_eq3(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_eq3(self, cls: type[MultiDict[str]]) -> None: d1 = cls([("key", "value1")]) d2 = cls() @@ -420,7 +432,7 @@ class BaseMultiDictTest: def test_eq_other_mapping_contains_more_keys( self, - cls: Type[MutableMultiMapping[str]], + cls: type[MultiDict[str]], ) -> None: d1 = cls(foo="bar") d2 = dict(foo="bar", bar="baz") @@ -428,7 +440,7 @@ class BaseMultiDictTest: assert d1 != d2 def test_eq_bad_mapping_len( - self, cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]] + self, cls: Union[type[MultiDict[int]], type[CIMultiDict[int]]] ) -> None: class BadMapping(Mapping[str, int]): def __getitem__(self, key: str) -> int: @@ -437,8 +449,8 @@ class BaseMultiDictTest: def __iter__(self) -> Iterator[str]: yield "a" # pragma: no cover # `len()` fails earlier - def __len__(self) -> int: # type: ignore[return] - 1 / 0 + def __len__(self) -> int: + return 1 // 0 d1 = cls(a=1) d2 = BadMapping() @@ -447,11 +459,11 @@ class BaseMultiDictTest: def test_eq_bad_mapping_getitem( self, - cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]], + cls: Union[type[MultiDict[int]], type[CIMultiDict[int]]], ) -> None: class BadMapping(Mapping[str, int]): - def __getitem__(self, key: str) -> int: # type: ignore[return] - 1 / 0 + def __getitem__(self, key: str) -> int: + return 1 // 0 def __iter__(self) -> Iterator[str]: yield "a" # pragma: no cover # foreign objects no iterated @@ -464,24 +476,22 @@ class BaseMultiDictTest: with pytest.raises(ZeroDivisionError): d1 == d2 - def test_ne(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_ne(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) assert d != {"key": "another_value"} - def test_and(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_and(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) assert {"key"} == d.keys() & {"key", "key2"} - def test_and2(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_and2(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) 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[MultiDict[str]]) -> None: d = cls([("key", "value1")]) sentinel_operation_result = object() @@ -493,26 +503,22 @@ class BaseMultiDictTest: 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[MultiDict[str]]) -> None: d = cls([("key", "value1")]) assert {"key"} == d.keys() & ["key", "key2"] - def test_or(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_or(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) assert {"key", "key2"} == d.keys() | {"key2"} - def test_or2(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_or2(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) assert {"key", "key2"} == {"key2"} | d.keys() - def test_bitwise_or_not_implemented( - self, cls: Type[MutableMultiMapping[str]] - ) -> None: + def test_bitwise_or_not_implemented(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) sentinel_operation_result = object() @@ -524,24 +530,22 @@ class BaseMultiDictTest: assert d.keys() | RightOperand() is sentinel_operation_result - def test_bitwise_or_iterable_not_set( - self, cls: Type[MutableMultiMapping[str]] - ) -> None: + def test_bitwise_or_iterable_not_set(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")]) assert {"key", "key2"} == d.keys() | ["key2"] - def test_sub(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_sub(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) assert {"key"} == d.keys() - {"key2"} - def test_sub2(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_sub2(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) assert {"key3"} == {"key", "key2", "key3"} - d.keys() - def test_sub_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_sub_not_implemented(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) sentinel_operation_result = object() @@ -553,22 +557,22 @@ class BaseMultiDictTest: assert d.keys() - RightOperand() is sentinel_operation_result - def test_sub_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_sub_iterable_not_set(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) assert {"key"} == d.keys() - ["key2"] - def test_xor(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_xor(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) assert {"key", "key3"} == d.keys() ^ {"key2", "key3"} - def test_xor2(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_xor2(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) assert {"key", "key3"} == {"key2", "key3"} ^ d.keys() - def test_xor_not_implemented(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_xor_not_implemented(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) sentinel_operation_result = object() @@ -580,7 +584,7 @@ class BaseMultiDictTest: assert d.keys() ^ RightOperand() is sentinel_operation_result - def test_xor_iterable_not_set(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_xor_iterable_not_set(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1"), ("key2", "value2")]) assert {"key", "key3"} == d.keys() ^ ["key2", "key3"] @@ -590,13 +594,13 @@ class BaseMultiDictTest: (("key2", "v", True), ("key", "value1", False)), ) def test_isdisjoint( - self, cls: Type[MutableMultiMapping[str]], key: str, value: str, expected: bool + self, cls: type[MultiDict[str]], key: str, value: str, expected: bool ) -> None: d = cls([("key", "value1")]) assert d.items().isdisjoint({(key, value)}) is expected assert d.keys().isdisjoint({key}) is expected - def test_repr_aiohttp_issue_410(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_repr_aiohttp_issue_410(self, cls: type[MutableMultiMapping[str]]) -> None: d = cls() try: @@ -614,9 +618,9 @@ class BaseMultiDictTest: @pytest.mark.parametrize("other", ({"other"},)) def test_op_issue_aiohttp_issue_410( self, - cls: Type[MutableMultiMapping[str]], + cls: type[MultiDict[str]], op: Callable[[object, object], object], - other: Set[str], + other: set[str], ) -> None: d = cls([("key", "value")]) @@ -628,7 +632,7 @@ class BaseMultiDictTest: assert sys.exc_info()[1] == e # noqa: PT017 - def test_weakref(self, cls: Type[MutableMultiMapping[str]]) -> None: + def test_weakref(self, cls: type[MutableMultiMapping[str]]) -> None: called = False def cb(wr: object) -> None: @@ -644,7 +648,7 @@ class BaseMultiDictTest: def test_iter_length_hint_keys( self, - cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]], + cls: Union[type[MultiDict[int]], type[CIMultiDict[int]]], ) -> None: md = cls(a=1, b=2) it = iter(md.keys()) @@ -652,7 +656,7 @@ class BaseMultiDictTest: def test_iter_length_hint_items( self, - cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]], + cls: Union[type[MultiDict[int]], type[CIMultiDict[int]]], ) -> None: md = cls(a=1, b=2) it = iter(md.items()) @@ -660,15 +664,15 @@ class BaseMultiDictTest: def test_iter_length_hint_values( self, - cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]], + cls: Union[type[MultiDict[int]], type[CIMultiDict[int]]], ) -> None: md = cls(a=1, b=2) it = iter(md.values()) - assert it.__length_hint__() == 2 # type: ignore[attr-defined] + assert it.__length_hint__() == 2 def test_ctor_list_arg_and_kwds( self, - cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]], + cls: Union[type[MultiDict[int]], type[CIMultiDict[int]]], ) -> None: arg = [("a", 1)] obj = cls(arg, b=2) @@ -677,7 +681,7 @@ class BaseMultiDictTest: def test_ctor_tuple_arg_and_kwds( self, - cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]], + cls: Union[type[MultiDict[int]], type[CIMultiDict[int]]], ) -> None: arg = (("a", 1),) obj = cls(arg, b=2) @@ -686,7 +690,7 @@ class BaseMultiDictTest: def test_ctor_deque_arg_and_kwds( self, - cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]], + cls: Union[type[MultiDict[int]], type[CIMultiDict[int]]], ) -> None: arg = deque([("a", 1)]) obj = cls(arg, b=2) @@ -709,7 +713,7 @@ class TestMultiDict(BaseMultiDictTest): """Make a case-sensitive multidict class/proxy constructor.""" return chained_callable(multidict_module, request.param) - def test__repr__(self, cls: Type[MultiDict[str]]) -> None: + def test__repr__(self, cls: type[MultiDict[str]]) -> None: d = cls() _cls = type(d) @@ -719,7 +723,7 @@ class TestMultiDict(BaseMultiDictTest): assert str(d) == "<%s('key': 'one', 'key': 'two')>" % _cls.__name__ - def test_getall(self, cls: Type[MultiDict[str]]) -> None: + def test_getall(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")], key="value2") assert d != {"key": "value1"} @@ -735,27 +739,27 @@ class TestMultiDict(BaseMultiDictTest): def test_preserve_stable_ordering( self, - cls: Type[MultiDict[Union[str, int]]], + cls: type[MultiDict[Union[str, int]]], ) -> None: d = cls([("a", 1), ("b", "2"), ("a", 3)]) s = "&".join("{}={}".format(k, v) for k, v in d.items()) assert s == "a=1&b=2&a=3" - def test_get(self, cls: Type[MultiDict[int]]) -> None: + def test_get(self, cls: type[MultiDict[int]]) -> None: d = cls([("a", 1), ("a", 2)]) assert d["a"] == 1 - def test_items__repr__(self, cls: Type[MultiDict[str]]) -> None: + def test_items__repr__(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")], key="value2") expected = "_ItemsView('key': 'value1', 'key': 'value2')" assert repr(d.items()) == expected - def test_keys__repr__(self, cls: Type[MultiDict[str]]) -> None: + def test_keys__repr__(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")], key="value2") assert repr(d.keys()) == "_KeysView('key', 'key')" - def test_values__repr__(self, cls: Type[MultiDict[str]]) -> None: + def test_values__repr__(self, cls: type[MultiDict[str]]) -> None: d = cls([("key", "value1")], key="value2") assert repr(d.values()) == "_ValuesView('value1', 'value2')" @@ -775,7 +779,7 @@ class TestCIMultiDict(BaseMultiDictTest): """Make a case-insensitive multidict class/proxy constructor.""" return chained_callable(multidict_module, request.param) - def test_basics(self, cls: Type[CIMultiDict[str]]) -> None: + def test_basics(self, cls: type[CIMultiDict[str]]) -> None: d = cls([("KEY", "value1")], KEY="value2") assert d.getone("key") == "value1" @@ -789,7 +793,7 @@ class TestCIMultiDict(BaseMultiDictTest): with pytest.raises(KeyError, match="key2"): d.getone("key2") - def test_getall(self, cls: Type[CIMultiDict[str]]) -> None: + def test_getall(self, cls: type[CIMultiDict[str]]) -> None: d = cls([("KEY", "value1")], KEY="value2") assert not d == {"KEY": "value1"} @@ -800,26 +804,26 @@ class TestCIMultiDict(BaseMultiDictTest): with pytest.raises(KeyError, match="some_key"): d.getall("some_key") - def test_get(self, cls: Type[CIMultiDict[int]]) -> None: + def test_get(self, cls: type[CIMultiDict[int]]) -> None: d = cls([("A", 1), ("a", 2)]) assert 1 == d["a"] - def test__repr__(self, cls: Type[CIMultiDict[str]]) -> None: + def test__repr__(self, cls: type[CIMultiDict[str]]) -> None: d = cls([("KEY", "value1")], key="value2") _cls = type(d) expected = "<%s('KEY': 'value1', 'key': 'value2')>" % _cls.__name__ assert str(d) == expected - def test_items__repr__(self, cls: Type[CIMultiDict[str]]) -> None: + def test_items__repr__(self, cls: type[CIMultiDict[str]]) -> None: d = cls([("KEY", "value1")], key="value2") expected = "_ItemsView('KEY': 'value1', 'key': 'value2')" assert repr(d.items()) == expected - def test_keys__repr__(self, cls: Type[CIMultiDict[str]]) -> None: + def test_keys__repr__(self, cls: type[CIMultiDict[str]]) -> None: d = cls([("KEY", "value1")], key="value2") assert repr(d.keys()) == "_KeysView('KEY', 'key')" - def test_values__repr__(self, cls: Type[CIMultiDict[str]]) -> None: + def test_values__repr__(self, cls: type[CIMultiDict[str]]) -> None: d = cls([("KEY", "value1")], key="value2") assert repr(d.values()) == "_ValuesView('value1', 'value2')" diff --git a/contrib/python/multidict/tests/test_multidict_benchmarks.py b/contrib/python/multidict/tests/test_multidict_benchmarks.py new file mode 100644 index 00000000000..e6a538f3ccf --- /dev/null +++ b/contrib/python/multidict/tests/test_multidict_benchmarks.py @@ -0,0 +1,391 @@ +"""codspeed benchmarks for multidict.""" + +from typing import Dict, Union + +from pytest_codspeed import BenchmarkFixture + +from multidict import CIMultiDict, MultiDict, istr + +# Note that this benchmark should not be refactored to use pytest.mark.parametrize +# since each benchmark name should be unique. + +_SENTINEL = object() + + +def test_multidict_insert_str(benchmark: BenchmarkFixture) -> None: + md: MultiDict[str] = MultiDict() + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md[i] = i + + +def test_cimultidict_insert_str(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[str] = CIMultiDict() + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md[i] = i + + +def test_cimultidict_insert_istr(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[istr] = CIMultiDict() + items = [istr(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md[i] = i + + +def test_multidict_add_str(benchmark: BenchmarkFixture) -> None: + md: MultiDict[str] = MultiDict() + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md.add(i, i) + + +def test_cimultidict_add_str(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[str] = CIMultiDict() + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md.add(i, i) + + +def test_cimultidict_add_istr(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[istr] = CIMultiDict() + items = [istr(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md.add(i, i) + + +def test_multidict_pop_str(benchmark: BenchmarkFixture) -> None: + md_base: MultiDict[str] = MultiDict((str(i), str(i)) for i in range(100)) + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + md = md_base.copy() + for i in items: + md.pop(i) + + +def test_cimultidict_pop_str(benchmark: BenchmarkFixture) -> None: + md_base: CIMultiDict[str] = CIMultiDict((str(i), str(i)) for i in range(100)) + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + md = md_base.copy() + for i in items: + md.pop(i) + + +def test_cimultidict_pop_istr(benchmark: BenchmarkFixture) -> None: + md_base: CIMultiDict[istr] = CIMultiDict((istr(i), istr(i)) for i in range(100)) + items = [istr(i) for i in range(100)] + + @benchmark + def _run() -> None: + md = md_base.copy() + for i in items: + md.pop(i) + + +def test_multidict_popitem_str(benchmark: BenchmarkFixture) -> None: + md_base: MultiDict[str] = MultiDict((str(i), str(i)) for i in range(100)) + + @benchmark + def _run() -> None: + md = md_base.copy() + for _ in range(100): + md.popitem() + + +def test_cimultidict_popitem_str(benchmark: BenchmarkFixture) -> None: + md_base: MultiDict[str] = MultiDict((str(i), str(i)) for i in range(100)) + + @benchmark + def _run() -> None: + md = md_base.copy() + for _ in range(100): + md.popitem() + + +def test_multidict_clear_str(benchmark: BenchmarkFixture) -> None: + md: MultiDict[str] = MultiDict((str(i), str(i)) for i in range(100)) + + @benchmark + def _run() -> None: + md.clear() + + +def test_cimultidict_clear_str(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[str] = CIMultiDict((str(i), str(i)) for i in range(100)) + + @benchmark + def _run() -> None: + md.clear() + + +def test_multidict_update_str(benchmark: BenchmarkFixture) -> None: + md: MultiDict[str] = MultiDict((str(i), str(i)) for i in range(100)) + items = {str(i): str(i) for i in range(100, 200)} + + @benchmark + def _run() -> None: + md.update(items) + + +def test_cimultidict_update_str(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[str] = CIMultiDict((str(i), str(i)) for i in range(100)) + items = {str(i): str(i) for i in range(100, 200)} + + @benchmark + def _run() -> None: + md.update(items) + + +def test_cimultidict_update_istr(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[istr] = CIMultiDict((istr(i), istr(i)) for i in range(100)) + items: Dict[Union[str, istr], istr] = {istr(i): istr(i) for i in range(100, 200)} + + @benchmark + def _run() -> None: + md.update(items) + + +def test_multidict_extend_str(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[str] = CIMultiDict((str(i), str(i)) for i in range(100)) + items = {str(i): str(i) for i in range(200)} + + @benchmark + def _run() -> None: + md.extend(items) + + +def test_cimultidict_extend_str(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[str] = CIMultiDict((str(i), str(i)) for i in range(100)) + items = {str(i): str(i) for i in range(200)} + + @benchmark + def _run() -> None: + md.extend(items) + + +def test_cimultidict_extend_istr(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[istr] = CIMultiDict((istr(i), istr(i)) for i in range(100)) + items = {istr(i): istr(i) for i in range(200)} + + @benchmark + def _run() -> None: + md.extend(items) + + +def test_multidict_delitem_str(benchmark: BenchmarkFixture) -> None: + md_base: MultiDict[str] = MultiDict((str(i), str(i)) for i in range(100)) + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + md = md_base.copy() + for i in items: + del md[i] + + +def test_cimultidict_delitem_str(benchmark: BenchmarkFixture) -> None: + md_base: CIMultiDict[str] = CIMultiDict((str(i), str(i)) for i in range(100)) + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + md = md_base.copy() + for i in items: + del md[i] + + +def test_cimultidict_delitem_istr(benchmark: BenchmarkFixture) -> None: + md_base: CIMultiDict[istr] = CIMultiDict((istr(i), istr(i)) for i in range(100)) + items = [istr(i) for i in range(100)] + + @benchmark + def _run() -> None: + md = md_base.copy() + for i in items: + del md[i] + + +def test_multidict_getall_str_hit(benchmark: BenchmarkFixture) -> None: + md: MultiDict[str] = MultiDict(("all", str(i)) for i in range(100)) + + @benchmark + def _run() -> None: + md.getall("all") + + +def test_cimultidict_getall_str_hit(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[str] = CIMultiDict(("all", str(i)) for i in range(100)) + + @benchmark + def _run() -> None: + md.getall("all") + + +def test_cimultidict_getall_istr_hit(benchmark: BenchmarkFixture) -> None: + all_istr = istr("all") + md: CIMultiDict[istr] = CIMultiDict((all_istr, istr(i)) for i in range(100)) + + @benchmark + def _run() -> None: + md.getall(all_istr) + + +def test_multidict_fetch(benchmark: BenchmarkFixture) -> None: + md: MultiDict[str] = MultiDict((str(i), str(i)) for i in range(100)) + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md[i] + + +def test_cimultidict_fetch_str(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[str] = CIMultiDict((str(i), str(i)) for i in range(100)) + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md[i] + + +def test_cimultidict_fetch_istr(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[istr] = CIMultiDict((istr(i), istr(i)) for i in range(100)) + items = [istr(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md[i] + + +def test_multidict_get_hit(benchmark: BenchmarkFixture) -> None: + md: MultiDict[str] = MultiDict((str(i), str(i)) for i in range(100)) + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md.get(i) + + +def test_multidict_get_miss(benchmark: BenchmarkFixture) -> None: + md: MultiDict[str] = MultiDict((str(i), str(i)) for i in range(100)) + items = [str(i) for i in range(100, 200)] + + @benchmark + def _run() -> None: + for i in items: + md.get(i) + + +def test_cimultidict_get_hit(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[str] = CIMultiDict((str(i), str(i)) for i in range(100)) + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md.get(i) + + +def test_cimultidict_get_miss(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[str] = CIMultiDict((str(i), str(i)) for i in range(100)) + items = [str(i) for i in range(100, 200)] + + @benchmark + def _run() -> None: + for i in items: + md.get(i) + + +def test_cimultidict_get_istr_hit(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[istr] = CIMultiDict((istr(i), istr(i)) for i in range(100)) + items = [istr(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md.get(i) + + +def test_cimultidict_get_istr_miss(benchmark: BenchmarkFixture) -> None: + md: CIMultiDict[istr] = CIMultiDict((istr(i), istr(i)) for i in range(100)) + items = [istr(i) for i in range(100, 200)] + + @benchmark + def _run() -> None: + for i in items: + md.get(i) + + +def test_cimultidict_get_hit_with_default( + benchmark: BenchmarkFixture, +) -> None: + md: CIMultiDict[str] = CIMultiDict((str(i), str(i)) for i in range(100)) + items = [str(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md.get(i, _SENTINEL) + + +def test_cimultidict_get_miss_with_default( + benchmark: BenchmarkFixture, +) -> None: + md: CIMultiDict[str] = CIMultiDict((str(i), str(i)) for i in range(100)) + items = [str(i) for i in range(100, 200)] + + @benchmark + def _run() -> None: + for i in items: + md.get(i, _SENTINEL) + + +def test_cimultidict_get_istr_hit_with_default( + benchmark: BenchmarkFixture, +) -> None: + md: CIMultiDict[istr] = CIMultiDict((istr(i), istr(i)) for i in range(100)) + items = [istr(i) for i in range(100)] + + @benchmark + def _run() -> None: + for i in items: + md.get(i, _SENTINEL) + + +def test_cimultidict_get_istr_with_default_miss( + benchmark: BenchmarkFixture, +) -> None: + md: CIMultiDict[istr] = CIMultiDict((istr(i), istr(i)) for i in range(100)) + items = [istr(i) for i in range(100, 200)] + + @benchmark + def _run() -> None: + for i in items: + md.get(i, _SENTINEL) diff --git a/contrib/python/multidict/tests/test_mutable_multidict.py b/contrib/python/multidict/tests/test_mutable_multidict.py index 3cacec25af9..45f1cdf5f67 100644 --- a/contrib/python/multidict/tests/test_mutable_multidict.py +++ b/contrib/python/multidict/tests/test_mutable_multidict.py @@ -1,16 +1,16 @@ import string import sys -from typing import Type +from typing import Union import pytest -from multidict import MultiMapping, MutableMultiMapping +from multidict import CIMultiDict, CIMultiDictProxy, MultiDictProxy, istr class TestMutableMultiDict: def test_copy( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d1 = case_sensitive_multidict_class(key="value", a="b") @@ -20,7 +20,7 @@ class TestMutableMultiDict: def test__repr__( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class() assert str(d) == "<%s()>" % case_sensitive_multidict_class.__name__ @@ -35,7 +35,7 @@ class TestMutableMultiDict: def test_getall( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class([("key", "value1")], key="value2") assert len(d) == 2 @@ -50,7 +50,7 @@ class TestMutableMultiDict: def test_add( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class() @@ -73,7 +73,7 @@ class TestMutableMultiDict: def test_extend( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[Union[str, int]]], ) -> None: d = case_sensitive_multidict_class() assert d == {} @@ -101,12 +101,12 @@ class TestMutableMultiDict: assert 6 == len(d) with pytest.raises(TypeError): - d.extend("foo", "bar") + d.extend("foo", "bar") # type: ignore[arg-type, call-arg] def test_extend_from_proxy( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], - case_sensitive_multidict_proxy_class: Type[MultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], + case_sensitive_multidict_proxy_class: type[MultiDictProxy[str]], ) -> None: d = case_sensitive_multidict_class([("a", "a"), ("b", "b")]) proxy = case_sensitive_multidict_proxy_class(d) @@ -118,7 +118,7 @@ class TestMutableMultiDict: def test_clear( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class([("key", "one")], key="two", foo="bar") @@ -128,7 +128,7 @@ class TestMutableMultiDict: def test_del( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class([("key", "one"), ("key", "two")], foo="bar") assert list(d.keys()) == ["key", "key", "foo"] @@ -142,7 +142,7 @@ class TestMutableMultiDict: def test_set_default( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class([("key", "one"), ("key", "two")], foo="bar") assert "one" == d.setdefault("key", "three") @@ -152,7 +152,7 @@ class TestMutableMultiDict: def test_popitem( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class() d.add("key", "val1") @@ -163,7 +163,7 @@ class TestMutableMultiDict: def test_popitem_empty_multidict( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class() @@ -172,7 +172,7 @@ class TestMutableMultiDict: def test_pop( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class() d.add("key", "val1") @@ -183,7 +183,7 @@ class TestMutableMultiDict: def test_pop2( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class() d.add("key", "val1") @@ -195,7 +195,7 @@ class TestMutableMultiDict: def test_pop_default( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class(other="val") @@ -204,7 +204,7 @@ class TestMutableMultiDict: def test_pop_raises( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class(other="val") @@ -215,7 +215,7 @@ class TestMutableMultiDict: def test_replacement_order( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class() d.add("key1", "val1") @@ -231,16 +231,16 @@ class TestMutableMultiDict: def test_nonstr_key( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class() with pytest.raises(TypeError): - d[1] = "val" + d[1] = "val" # type: ignore[index] def test_istr_key( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], - case_insensitive_str_class: Type[str], + case_sensitive_multidict_class: type[CIMultiDict[str]], + case_insensitive_str_class: type[str], ) -> None: d = case_sensitive_multidict_class() d[case_insensitive_str_class("1")] = "val" @@ -248,7 +248,7 @@ class TestMutableMultiDict: def test_str_derived_key( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: class A(str): pass @@ -259,8 +259,8 @@ class TestMutableMultiDict: def test_istr_key_add( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], - case_insensitive_str_class: Type[str], + case_sensitive_multidict_class: type[CIMultiDict[str]], + case_insensitive_str_class: type[str], ) -> None: d = case_sensitive_multidict_class() d.add(case_insensitive_str_class("1"), "val") @@ -268,7 +268,7 @@ class TestMutableMultiDict: def test_str_derived_key_add( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: class A(str): pass @@ -279,7 +279,7 @@ class TestMutableMultiDict: def test_popall( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class() d.add("key1", "val1") @@ -291,14 +291,14 @@ class TestMutableMultiDict: def test_popall_default( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class() assert "val" == d.popall("key", "val") def test_popall_key_error( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_sensitive_multidict_class() with pytest.raises(KeyError, match="key"): @@ -306,7 +306,7 @@ class TestMutableMultiDict: def test_large_multidict_resizing( self, - case_sensitive_multidict_class: Type[MutableMultiMapping[str]], + case_sensitive_multidict_class: type[CIMultiDict[int]], ) -> None: SIZE = 1024 d = case_sensitive_multidict_class() @@ -322,7 +322,7 @@ class TestMutableMultiDict: class TestCIMutableMultiDict: def test_getall( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class([("KEY", "value1")], KEY="value2") @@ -336,7 +336,7 @@ class TestCIMutableMultiDict: def test_ctor( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class(k1="v1") assert "v1" == d["K1"] @@ -344,7 +344,7 @@ class TestCIMutableMultiDict: def test_setitem( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class() d["k1"] = "v1" @@ -353,7 +353,7 @@ class TestCIMutableMultiDict: def test_delitem( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class() d["k1"] = "v1" @@ -363,7 +363,7 @@ class TestCIMutableMultiDict: def test_copy( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d1 = case_insensitive_multidict_class(key="KEY", a="b") @@ -374,7 +374,7 @@ class TestCIMutableMultiDict: def test__repr__( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class() assert str(d) == "<%s()>" % case_insensitive_multidict_class.__name__ @@ -389,7 +389,7 @@ class TestCIMutableMultiDict: def test_add( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class() @@ -421,7 +421,7 @@ class TestCIMutableMultiDict: def test_extend( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[Union[str, int]]], ) -> None: d = case_insensitive_multidict_class() assert d == {} @@ -450,12 +450,12 @@ class TestCIMutableMultiDict: assert 6 == len(d) with pytest.raises(TypeError): - d.extend("foo", "bar") + d.extend("foo", "bar") # type: ignore[arg-type, call-arg] def test_extend_from_proxy( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], - case_insensitive_multidict_proxy_class: Type[MultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], + case_insensitive_multidict_proxy_class: type[CIMultiDictProxy[str]], ) -> None: d = case_insensitive_multidict_class([("a", "a"), ("b", "b")]) proxy = case_insensitive_multidict_proxy_class(d) @@ -467,7 +467,7 @@ class TestCIMutableMultiDict: def test_clear( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class([("KEY", "one")], key="two", foo="bar") @@ -477,7 +477,7 @@ class TestCIMutableMultiDict: def test_del( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class( [("KEY", "one"), ("key", "two")], @@ -493,7 +493,7 @@ class TestCIMutableMultiDict: def test_set_default( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class( [("KEY", "one"), ("key", "two")], @@ -507,7 +507,7 @@ class TestCIMutableMultiDict: def test_popitem( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class() d.add("KEY", "val1") @@ -520,7 +520,7 @@ class TestCIMutableMultiDict: def test_popitem_empty_multidict( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class() @@ -529,7 +529,7 @@ class TestCIMutableMultiDict: def test_pop( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class() d.add("KEY", "val1") @@ -540,7 +540,7 @@ class TestCIMutableMultiDict: def test_pop_lowercase( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class() d.add("KEY", "val1") @@ -551,7 +551,7 @@ class TestCIMutableMultiDict: def test_pop_default( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class(OTHER="val") @@ -560,7 +560,7 @@ class TestCIMutableMultiDict: def test_pop_raises( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d = case_insensitive_multidict_class(OTHER="val") @@ -571,8 +571,8 @@ class TestCIMutableMultiDict: def test_extend_with_istr( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], - case_insensitive_str_class: Type[str], + case_insensitive_multidict_class: type[CIMultiDict[str]], + case_insensitive_str_class: type[istr], ) -> None: us = case_insensitive_str_class("aBc") d = case_insensitive_multidict_class() @@ -582,8 +582,8 @@ class TestCIMutableMultiDict: def test_copy_istr( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], - case_insensitive_str_class: Type[str], + case_insensitive_multidict_class: type[CIMultiDict[str]], + case_insensitive_str_class: type[istr], ) -> None: d = case_insensitive_multidict_class({case_insensitive_str_class("Foo"): "bar"}) d2 = d.copy() @@ -591,7 +591,7 @@ class TestCIMutableMultiDict: def test_eq( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: d1 = case_insensitive_multidict_class(Key="val") d2 = case_insensitive_multidict_class(KEY="val") @@ -604,7 +604,7 @@ class TestCIMutableMultiDict: ) def test_sizeof( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: md = case_insensitive_multidict_class() s1 = sys.getsizeof(md) @@ -621,14 +621,14 @@ class TestCIMutableMultiDict: ) def test_min_sizeof( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: md = case_insensitive_multidict_class() assert sys.getsizeof(md) < 1024 def test_issue_620_items( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: # https://github.com/aio-libs/multidict/issues/620 d = case_insensitive_multidict_class({"a": "123, 456", "b": "789"}) @@ -639,7 +639,7 @@ class TestCIMutableMultiDict: def test_issue_620_keys( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: # https://github.com/aio-libs/multidict/issues/620 d = case_insensitive_multidict_class({"a": "123, 456", "b": "789"}) @@ -650,7 +650,7 @@ class TestCIMutableMultiDict: def test_issue_620_values( self, - case_insensitive_multidict_class: Type[MutableMultiMapping[str]], + case_insensitive_multidict_class: type[CIMultiDict[str]], ) -> None: # https://github.com/aio-libs/multidict/issues/620 d = case_insensitive_multidict_class({"a": "123, 456", "b": "789"}) diff --git a/contrib/python/multidict/tests/test_pickle.py b/contrib/python/multidict/tests/test_pickle.py index 48adea13f0f..3159ea45c64 100644 --- a/contrib/python/multidict/tests/test_pickle.py +++ b/contrib/python/multidict/tests/test_pickle.py @@ -1,13 +1,21 @@ import pickle from pathlib import Path +from typing import TYPE_CHECKING import pytest +from multidict import MultiDict, MultiDictProxy + +if TYPE_CHECKING: + from conftest import MultidictImplementation + import yatest.common as yc here = Path(yc.source_path(__file__)).resolve().parent -def test_pickle(any_multidict_class, pickle_protocol): +def test_pickle( + any_multidict_class: type[MultiDict[int]], pickle_protocol: int +) -> None: d = any_multidict_class([("a", 1), ("a", 2)]) pbytes = pickle.dumps(d, pickle_protocol) obj = pickle.loads(pbytes) @@ -15,14 +23,21 @@ def test_pickle(any_multidict_class, pickle_protocol): assert isinstance(obj, any_multidict_class) -def test_pickle_proxy(any_multidict_class, any_multidict_proxy_class): +def test_pickle_proxy( + any_multidict_class: type[MultiDict[int]], + any_multidict_proxy_class: type[MultiDictProxy[int]], +) -> None: d = any_multidict_class([("a", 1), ("a", 2)]) proxy = any_multidict_proxy_class(d) with pytest.raises(TypeError): pickle.dumps(proxy) -def test_load_from_file(any_multidict_class, multidict_implementation, pickle_protocol): +def test_load_from_file( + any_multidict_class: type[MultiDict[int]], + multidict_implementation: "MultidictImplementation", + pickle_protocol: int, +) -> None: multidict_class_name = any_multidict_class.__name__ pickle_file_basename = "-".join( ( diff --git a/contrib/python/multidict/tests/test_types.py b/contrib/python/multidict/tests/test_types.py index ceaa391e379..6339006b68f 100644 --- a/contrib/python/multidict/tests/test_types.py +++ b/contrib/python/multidict/tests/test_types.py @@ -1,52 +1,57 @@ -import sys import types import pytest -def test_proxies(multidict_module): +def test_proxies(multidict_module: types.ModuleType) -> None: assert issubclass( multidict_module.CIMultiDictProxy, multidict_module.MultiDictProxy, ) -def test_dicts(multidict_module): +def test_dicts(multidict_module: types.ModuleType) -> None: assert issubclass(multidict_module.CIMultiDict, multidict_module.MultiDict) -def test_proxy_not_inherited_from_dict(multidict_module): +def test_proxy_not_inherited_from_dict(multidict_module: types.ModuleType) -> None: assert not issubclass(multidict_module.MultiDictProxy, multidict_module.MultiDict) -def test_dict_not_inherited_from_proxy(multidict_module): +def test_dict_not_inherited_from_proxy(multidict_module: types.ModuleType) -> None: assert not issubclass(multidict_module.MultiDict, multidict_module.MultiDictProxy) -def test_multidict_proxy_copy_type(multidict_module): +def test_multidict_proxy_copy_type(multidict_module: types.ModuleType) -> None: d = multidict_module.MultiDict(key="val") p = multidict_module.MultiDictProxy(d) assert isinstance(p.copy(), multidict_module.MultiDict) -def test_cimultidict_proxy_copy_type(multidict_module): +def test_cimultidict_proxy_copy_type(multidict_module: types.ModuleType) -> None: d = multidict_module.CIMultiDict(key="val") p = multidict_module.CIMultiDictProxy(d) assert isinstance(p.copy(), multidict_module.CIMultiDict) -def test_create_multidict_proxy_from_nonmultidict(multidict_module): +def test_create_multidict_proxy_from_nonmultidict( + multidict_module: types.ModuleType, +) -> None: with pytest.raises(TypeError): multidict_module.MultiDictProxy({}) -def test_create_multidict_proxy_from_cimultidict(multidict_module): +def test_create_multidict_proxy_from_cimultidict( + multidict_module: types.ModuleType, +) -> None: d = multidict_module.CIMultiDict(key="val") p = multidict_module.MultiDictProxy(d) assert p == d -def test_create_multidict_proxy_from_multidict_proxy_from_mdict(multidict_module): +def test_create_multidict_proxy_from_multidict_proxy_from_mdict( + multidict_module: types.ModuleType, +) -> None: d = multidict_module.MultiDict(key="val") p = multidict_module.MultiDictProxy(d) assert p == d @@ -54,7 +59,9 @@ def test_create_multidict_proxy_from_multidict_proxy_from_mdict(multidict_module assert p2 == p -def test_create_cimultidict_proxy_from_cimultidict_proxy_from_ci(multidict_module): +def test_create_cimultidict_proxy_from_cimultidict_proxy_from_ci( + multidict_module: types.ModuleType, +) -> None: d = multidict_module.CIMultiDict(key="val") p = multidict_module.CIMultiDictProxy(d) assert p == d @@ -62,7 +69,9 @@ def test_create_cimultidict_proxy_from_cimultidict_proxy_from_ci(multidict_modul assert p2 == p -def test_create_cimultidict_proxy_from_nonmultidict(multidict_module): +def test_create_cimultidict_proxy_from_nonmultidict( + multidict_module: types.ModuleType, +) -> None: with pytest.raises( TypeError, match=( @@ -73,7 +82,9 @@ def test_create_cimultidict_proxy_from_nonmultidict(multidict_module): multidict_module.CIMultiDictProxy({}) -def test_create_ci_multidict_proxy_from_multidict(multidict_module): +def test_create_ci_multidict_proxy_from_multidict( + multidict_module: types.ModuleType, +) -> None: d = multidict_module.MultiDict(key="val") with pytest.raises( TypeError, @@ -85,20 +96,7 @@ def test_create_ci_multidict_proxy_from_multidict(multidict_module): multidict_module.CIMultiDictProxy(d) -@pytest.mark.skipif( - sys.version_info >= (3, 9), reason="Python 3.9 uses GenericAlias which is different" -) -def test_generic_exists(multidict_module) -> None: - assert multidict_module.MultiDict[int] is multidict_module.MultiDict - assert multidict_module.MultiDictProxy[int] is multidict_module.MultiDictProxy - assert multidict_module.CIMultiDict[int] is multidict_module.CIMultiDict - assert multidict_module.CIMultiDictProxy[int] is multidict_module.CIMultiDictProxy - - -@pytest.mark.skipif( - sys.version_info < (3, 9), reason="Python 3.9 is required for GenericAlias" -) -def test_generic_alias(multidict_module) -> None: +def test_generic_alias(multidict_module: types.ModuleType) -> None: assert multidict_module.MultiDict[int] == types.GenericAlias( multidict_module.MultiDict, (int,) ) diff --git a/contrib/python/multidict/tests/test_update.py b/contrib/python/multidict/tests/test_update.py index f4553278571..46ab30a08bd 100644 --- a/contrib/python/multidict/tests/test_update.py +++ b/contrib/python/multidict/tests/test_update.py @@ -1,10 +1,12 @@ from collections import deque -from typing import Type +from typing import Union -from multidict import MultiMapping +from multidict import CIMultiDict, MultiDict +_MD_Classes = Union[type[MultiDict[int]], type[CIMultiDict[int]]] -def test_update_replace(any_multidict_class: Type[MultiMapping[str]]) -> None: + +def test_update_replace(any_multidict_class: _MD_Classes) -> None: obj1 = any_multidict_class([("a", 1), ("b", 2), ("a", 3), ("c", 10)]) obj2 = any_multidict_class([("a", 4), ("b", 5), ("a", 6)]) obj1.update(obj2) @@ -12,7 +14,7 @@ def test_update_replace(any_multidict_class: Type[MultiMapping[str]]) -> None: assert list(obj1.items()) == expected -def test_update_append(any_multidict_class: Type[MultiMapping[str]]) -> None: +def test_update_append(any_multidict_class: _MD_Classes) -> None: obj1 = any_multidict_class([("a", 1), ("b", 2), ("a", 3), ("c", 10)]) obj2 = any_multidict_class([("a", 4), ("a", 5), ("a", 6)]) obj1.update(obj2) @@ -20,7 +22,7 @@ def test_update_append(any_multidict_class: Type[MultiMapping[str]]) -> None: assert list(obj1.items()) == expected -def test_update_remove(any_multidict_class: Type[MultiMapping[str]]) -> None: +def test_update_remove(any_multidict_class: _MD_Classes) -> None: obj1 = any_multidict_class([("a", 1), ("b", 2), ("a", 3), ("c", 10)]) obj2 = any_multidict_class([("a", 4)]) obj1.update(obj2) @@ -28,7 +30,7 @@ def test_update_remove(any_multidict_class: Type[MultiMapping[str]]) -> None: assert list(obj1.items()) == expected -def test_update_replace_seq(any_multidict_class: Type[MultiMapping[str]]) -> None: +def test_update_replace_seq(any_multidict_class: _MD_Classes) -> None: obj1 = any_multidict_class([("a", 1), ("b", 2), ("a", 3), ("c", 10)]) obj2 = [("a", 4), ("b", 5), ("a", 6)] obj1.update(obj2) @@ -36,14 +38,14 @@ def test_update_replace_seq(any_multidict_class: Type[MultiMapping[str]]) -> Non assert list(obj1.items()) == expected -def test_update_replace_seq2(any_multidict_class: Type[MultiMapping[str]]) -> None: +def test_update_replace_seq2(any_multidict_class: _MD_Classes) -> None: obj1 = any_multidict_class([("a", 1), ("b", 2), ("a", 3), ("c", 10)]) obj1.update([("a", 4)], b=5, a=6) expected = [("a", 4), ("b", 5), ("a", 6), ("c", 10)] assert list(obj1.items()) == expected -def test_update_append_seq(any_multidict_class: Type[MultiMapping[str]]) -> None: +def test_update_append_seq(any_multidict_class: _MD_Classes) -> None: obj1 = any_multidict_class([("a", 1), ("b", 2), ("a", 3), ("c", 10)]) obj2 = [("a", 4), ("a", 5), ("a", 6)] obj1.update(obj2) @@ -51,7 +53,7 @@ def test_update_append_seq(any_multidict_class: Type[MultiMapping[str]]) -> None assert list(obj1.items()) == expected -def test_update_remove_seq(any_multidict_class: Type[MultiMapping[str]]) -> None: +def test_update_remove_seq(any_multidict_class: _MD_Classes) -> None: obj1 = any_multidict_class([("a", 1), ("b", 2), ("a", 3), ("c", 10)]) obj2 = [("a", 4)] obj1.update(obj2) @@ -59,9 +61,7 @@ def test_update_remove_seq(any_multidict_class: Type[MultiMapping[str]]) -> None assert list(obj1.items()) == expected -def test_update_md( - case_sensitive_multidict_class: Type[MultiMapping[str]], -) -> None: +def test_update_md(case_sensitive_multidict_class: type[CIMultiDict[str]]) -> None: d = case_sensitive_multidict_class() d.add("key", "val1") d.add("key", "val2") @@ -73,8 +73,8 @@ def test_update_md( def test_update_istr_ci_md( - case_insensitive_multidict_class: Type[MultiMapping[str]], - case_insensitive_str_class: str, + case_insensitive_multidict_class: type[CIMultiDict[str]], + case_insensitive_str_class: type[str], ) -> None: d = case_insensitive_multidict_class() d.add(case_insensitive_str_class("KEY"), "val1") @@ -86,9 +86,7 @@ def test_update_istr_ci_md( assert [("key", "val"), ("key2", "val3")] == list(d.items()) -def test_update_ci_md( - case_insensitive_multidict_class: Type[MultiMapping[str]], -) -> None: +def test_update_ci_md(case_insensitive_multidict_class: type[CIMultiDict[str]]) -> None: d = case_insensitive_multidict_class() d.add("KEY", "val1") d.add("key", "val2") @@ -99,9 +97,7 @@ def test_update_ci_md( assert [("Key", "val"), ("key2", "val3")] == list(d.items()) -def test_update_list_arg_and_kwds( - any_multidict_class: Type[MultiMapping[str]], -) -> None: +def test_update_list_arg_and_kwds(any_multidict_class: _MD_Classes) -> None: obj = any_multidict_class() arg = [("a", 1)] obj.update(arg, b=2) @@ -109,9 +105,7 @@ def test_update_list_arg_and_kwds( assert arg == [("a", 1)] -def test_update_tuple_arg_and_kwds( - any_multidict_class: Type[MultiMapping[str]], -) -> None: +def test_update_tuple_arg_and_kwds(any_multidict_class: _MD_Classes) -> None: obj = any_multidict_class() arg = (("a", 1),) obj.update(arg, b=2) @@ -119,9 +113,7 @@ def test_update_tuple_arg_and_kwds( assert arg == (("a", 1),) -def test_update_deque_arg_and_kwds( - any_multidict_class: Type[MultiMapping[str]], -) -> None: +def test_update_deque_arg_and_kwds(any_multidict_class: _MD_Classes) -> None: obj = any_multidict_class() arg = deque([("a", 1)]) obj.update(arg, b=2) diff --git a/contrib/python/multidict/tests/test_version.py b/contrib/python/multidict/tests/test_version.py index e004afa1124..4fe209c6786 100644 --- a/contrib/python/multidict/tests/test_version.py +++ b/contrib/python/multidict/tests/test_version.py @@ -1,18 +1,25 @@ -from typing import Callable, Type +from collections.abc import Callable +from typing import TypeVar, Union import pytest -from multidict import MultiMapping +from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy +_T = TypeVar("_T") +_MD_Types = Union[ + MultiDict[_T], CIMultiDict[_T], MultiDictProxy[_T], CIMultiDictProxy[_T] +] +GetVersion = Callable[[_MD_Types[_T]], int] -def test_getversion_bad_param(multidict_getversion_callable): + +def test_getversion_bad_param(multidict_getversion_callable: GetVersion[str]) -> None: with pytest.raises(TypeError): - multidict_getversion_callable(1) + multidict_getversion_callable(1) # type: ignore[arg-type] def test_ctor( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m1 = any_multidict_class() v1 = multidict_getversion_callable(m1) @@ -22,8 +29,8 @@ def test_ctor( def test_add( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() v = multidict_getversion_callable(m) @@ -32,8 +39,8 @@ def test_add( def test_delitem( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -43,8 +50,8 @@ def test_delitem( def test_delitem_not_found( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -55,8 +62,8 @@ def test_delitem_not_found( def test_setitem( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -66,8 +73,8 @@ def test_setitem( def test_setitem_not_found( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -77,8 +84,8 @@ def test_setitem_not_found( def test_clear( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -88,8 +95,8 @@ def test_clear( def test_setdefault( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -99,8 +106,8 @@ def test_setdefault( def test_popone( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -110,8 +117,8 @@ def test_popone( def test_popone_default( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -121,8 +128,8 @@ def test_popone_default( def test_popone_key_error( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -133,8 +140,8 @@ def test_popone_key_error( def test_pop( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -144,8 +151,8 @@ def test_pop( def test_pop_default( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -155,8 +162,8 @@ def test_pop_default( def test_pop_key_error( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -167,8 +174,8 @@ def test_pop_key_error( def test_popall( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -178,8 +185,8 @@ def test_popall( def test_popall_default( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -189,8 +196,8 @@ def test_popall_default( def test_popall_key_error( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -201,8 +208,8 @@ def test_popall_key_error( def test_popitem( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() m.add("key", "val") @@ -212,8 +219,8 @@ def test_popitem( def test_popitem_key_error( - any_multidict_class: Type[MultiMapping[str]], - multidict_getversion_callable: Callable, + any_multidict_class: type[MultiDict[str]], + multidict_getversion_callable: GetVersion[str], ) -> None: m = any_multidict_class() v = multidict_getversion_callable(m) |