From ba632f8d5f97b2614bd3201d4a835537f88ea4a2 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Wed, 7 Aug 2024 14:13:21 +0300 Subject: [PATCH 01/44] timeout tokens summing optimization: the sum will be only token with near deadline --- cantok/tokens/abstract/abstract_token.py | 27 ++++++++++++++---------- cantok/tokens/timeout_token.py | 18 ++++++++++++++-- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index 286168e..4dfd361 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -1,7 +1,7 @@ from sys import getrefcount from abc import ABC, abstractmethod from threading import RLock -from typing import List, Dict, Awaitable, Optional, Union, Any +from typing import Tuple, List, Dict, Awaitable, Optional, Union, Any from cantok.errors import CancellationError @@ -15,17 +15,9 @@ class AbstractToken(ABC): rollback_if_nondirect_polling = False def __init__(self, *tokens: 'AbstractToken', cancelled: bool = False) -> None: - from cantok import DefaultToken - self.cached_report: Optional[CancellationReport] = None self._cancelled: bool = cancelled - self.tokens: List[AbstractToken] = [] - - for token in tokens: - if isinstance(token, DefaultToken): - pass - else: - self.tokens.append(token) + self.tokens: List[AbstractToken] = self.filter_tokens(tokens) self.lock: RLock = RLock() @@ -81,12 +73,25 @@ def __add__(self, item: 'AbstractToken') -> 'AbstractToken': if container_token is None: return SimpleToken(*nested_tokens) else: - container_token.tokens.extend(nested_tokens) + container_token.tokens.extend(container_token.filter_tokens(nested_tokens)) return container_token def __bool__(self) -> bool: return self.keep_on() + def filter_tokens(self, tokens: Tuple['AbstractToken', ...]) -> List['AbstractToken']: + from cantok import DefaultToken + + result: List[AbstractToken] = [] + + for token in tokens: + if isinstance(token, DefaultToken): + pass + else: + result.append(token) + + return result + @property def cancelled(self) -> bool: return self.is_cancelled() diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index 026d1ae..18280be 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -1,6 +1,6 @@ from time import monotonic_ns, perf_counter -from typing import Union, Callable, Dict, Any +from typing import Union, Callable, Tuple, List, Dict, Any from cantok import AbstractToken from cantok import ConditionToken @@ -25,11 +25,25 @@ def __init__(self, timeout: Union[int, float], *tokens: AbstractToken, cancelled timer = perf_counter start_time: Union[int, float] = timer() + deadline = start_time + timeout def function() -> bool: - return timer() >= (start_time + timeout) + return timer() >= deadline + + self.deadline = deadline super().__init__(function, *tokens, cancelled=cancelled) + def filter_tokens(self, tokens: Tuple['AbstractToken', ...]) -> List['AbstractToken']: + result: List[AbstractToken] = [] + + for token in tokens: + if isinstance(token, TimeoutToken) and token.monotonic == self.monotonic and self.deadline < token.deadline: + result.extend(token.tokens) + else: + result.append(token) + + return super().filter_tokens(result) + def text_representation_of_superpower(self) -> str: return str(self.timeout) From 81dcee00bc5fabc1e3751d362872e9a43f20fee4 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Wed, 7 Aug 2024 15:27:00 +0300 Subject: [PATCH 02/44] old tests fixed --- tests/units/tokens/abstract/test_abstract_token.py | 12 ++++++++---- tests/units/tokens/test_simple_token.py | 5 +---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/units/tokens/abstract/test_abstract_token.py b/tests/units/tokens/abstract/test_abstract_token.py index eeb15b4..d4f285d 100644 --- a/tests/units/tokens/abstract/test_abstract_token.py +++ b/tests/units/tokens/abstract/test_abstract_token.py @@ -173,10 +173,14 @@ def test_add_not_temp_tokens(first_token_fabric, second_token_fabric): def test_add_temp_tokens(first_token_class, second_token_class, first_arguments, second_arguments): tokens_sum = first_token_class(*first_arguments) + second_token_class(*second_arguments) - assert isinstance(tokens_sum, first_token_class) - assert len(tokens_sum.tokens) == 1 - assert isinstance(tokens_sum.tokens[0], second_token_class) - assert len(tokens_sum.tokens[0].tokens) == 0 + if not (first_token_class is TimeoutToken and second_token_class is TimeoutToken): + assert isinstance(tokens_sum, first_token_class) + assert len(tokens_sum.tokens) == 1 + assert isinstance(tokens_sum.tokens[0], second_token_class) + assert len(tokens_sum.tokens[0].tokens) == 0 + else: + assert isinstance(tokens_sum, TimeoutToken) + assert len(tokens_sum.tokens) == 0 @pytest.mark.parametrize( diff --git a/tests/units/tokens/test_simple_token.py b/tests/units/tokens/test_simple_token.py index 33a74a4..6763a92 100644 --- a/tests/units/tokens/test_simple_token.py +++ b/tests/units/tokens/test_simple_token.py @@ -196,12 +196,9 @@ def test_sum_of_2_temp_timeout_tokens_throw_right_temp_simple_token(): token = TimeoutToken(1) + SimpleToken(TimeoutToken(2)) assert isinstance(token, TimeoutToken) - assert len(token.tokens) == 1 + assert len(token.tokens) == 0 assert token.timeout == 1 - assert isinstance(token.tokens[0], TimeoutToken) - assert token.tokens[0].timeout == 2 - def test_sum_of_2_temp_timeout_tokens_throw_left_temp_simple_token(): token = SimpleToken(TimeoutToken(1)) + TimeoutToken(2) From 9d15f25e50a473d617c3575b4f2e526b3f1be72c Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 14:31:00 +0300 Subject: [PATCH 03/44] new tests --- tests/units/tokens/test_timeout_token.py | 374 +++++++++++++++++++++++ 1 file changed, 374 insertions(+) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index 15549c5..a5dfe75 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -329,3 +329,377 @@ def test_timeout_is_more_important_than_cache(): def test_zero_timeout_token_report_is_about_superpower(): for report in TimeoutToken(0).get_report(True), TimeoutToken(0).get_report(False): assert report.cause == CancelCause.SUPERPOWER + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_same_monotonic_flag(addictional_kwargs): + token = TimeoutToken(2, **addictional_kwargs) + TimeoutToken(1, **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 2 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == 1 + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_not_same_monotonic_flag(left_addictional_kwargs, right_addictional_kwargs): + token = TimeoutToken(2, **left_addictional_kwargs) + TimeoutToken(1, **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 2 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == 1 + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_temp_not_monotonic_timeout_token_with_same_monotonic_flag(timeout_for_equal_or_bigger_token, addictional_kwargs): + token = TimeoutToken(1, **addictional_kwargs) + TimeoutToken(timeout_for_equal_or_bigger_token, **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 0 + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_temp_not_monotonic_timeout_token_with_not_same_monotonic_flag(timeout_for_equal_or_bigger_token, left_addictional_kwargs, right_addictional_kwargs): + token = TimeoutToken(1, **left_addictional_kwargs) + TimeoutToken(timeout_for_equal_or_bigger_token, **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == timeout_for_equal_or_bigger_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_timeout_token_plus_less_temp_timeout_token_with_same_monotonic_flag(addictional_kwargs): + left_timeout_token = TimeoutToken(2, **addictional_kwargs) + token = left_timeout_token + TimeoutToken(1, **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token is not left_timeout_token + assert token.timeout == 1 + assert len(token.tokens) == 0 + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_timeout_token_plus_less_temp_timeout_token_with_not_same_monotonic_flag(left_addictional_kwargs, right_addictional_kwargs): + left_timeout_token = TimeoutToken(2, **left_addictional_kwargs) + token = left_timeout_token + TimeoutToken(1, **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == 2 + assert token.tokens[0] is left_timeout_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_not_monotonic_timeout_token_plus_bigger_temp_not_monotonic_timeout_token_with_same_monotonic_flag(addictional_kwargs): + left_timeout_token = TimeoutToken(1, **addictional_kwargs) + token = left_timeout_token + TimeoutToken(2, **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 2 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == 1 + assert token.tokens[0] is left_timeout_token + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_not_monotonic_timeout_token_plus_bigger_temp_not_monotonic_timeout_token_with_not_same_monotonic_flag(left_addictional_kwargs, right_addictional_kwargs): + left_timeout_token = TimeoutToken(1, **left_addictional_kwargs) + token = left_timeout_token + TimeoutToken(2, **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 2 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == 1 + assert token.tokens[0] is left_timeout_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_temp_timeout_token_plus_less_timeout_token_with_same_monotonic_flag(addictional_kwargs): + right_timeout_token = TimeoutToken(1, **addictional_kwargs) + token = TimeoutToken(2, **addictional_kwargs) + right_timeout_token + + assert isinstance(token, TimeoutToken) + assert token.timeout == 2 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == 1 + assert token.tokens[0] is right_timeout_token + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_temp_timeout_token_plus_less_timeout_token_with_not_same_monotonic_flag(left_addictional_kwargs, right_addictional_kwargs): + right_timeout_token = TimeoutToken(1, **right_addictional_kwargs) + token = TimeoutToken(2, **left_addictional_kwargs) + right_timeout_token + + assert isinstance(token, TimeoutToken) + assert token.timeout == 2 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == 1 + assert token.tokens[0] is right_timeout_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_temp_not_monotonic_timeout_token_plus_bigger_not_monotonic_timeout_token_with_same_monotonic_flag(addictional_kwargs): + right_timeout_token = TimeoutToken(2, **addictional_kwargs) + token = TimeoutToken(1, **addictional_kwargs) + right_timeout_token + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 0 + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_temp_not_monotonic_timeout_token_plus_bigger_not_monotonic_timeout_token_with_not_same_monotonic_flag(left_addictional_kwargs, right_addictional_kwargs): + right_timeout_token = TimeoutToken(2, **right_addictional_kwargs) + token = TimeoutToken(1, **left_addictional_kwargs) + right_timeout_token + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == 2 + assert token.tokens[0] is right_timeout_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_timeout_token_plus_less_timeout_token_with_same_monotonic_flag(addictional_kwargs): + left = TimeoutToken(2, **addictional_kwargs) + right = TimeoutToken(1, **addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[0].timeout == 2 + assert token.tokens[1].timeout == 1 + assert token.tokens[0] is left + assert token.tokens[1] is right + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_timeout_token_plus_less_timeout_token_with_not_same_monotonic_flag(left_addictional_kwargs, right_addictional_kwargs): + left = TimeoutToken(2, **left_addictional_kwargs) + right = TimeoutToken(1, **right_addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[0].timeout == 2 + assert token.tokens[1].timeout == 1 + assert token.tokens[0] is left + assert token.tokens[1] is right + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_or_equal_not_monotonic_timeout_token_plus_bigger_or_equal_not_monotonic_timeout_token_with_same_monotonic_flag(timeout_for_equal_or_bigger_token, addictional_kwargs): + left = TimeoutToken(1, **addictional_kwargs) + right = TimeoutToken(timeout_for_equal_or_bigger_token, **addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[0].timeout == 1 + assert token.tokens[1].timeout == timeout_for_equal_or_bigger_token + assert token.tokens[0] is left + assert token.tokens[1] is right + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_or_equal_not_monotonic_timeout_token_plus_bigger_or_equal_not_monotonic_timeout_token_with_not_same_monotonic_flag(timeout_for_equal_or_bigger_token, left_addictional_kwargs, right_addictional_kwargs): + left = TimeoutToken(1, **left_addictional_kwargs) + right = TimeoutToken(timeout_for_equal_or_bigger_token, **right_addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[0].timeout == 1 + assert token.tokens[1].timeout == timeout_for_equal_or_bigger_token + assert token.tokens[0] is left + assert token.tokens[1] is right From af50521c1cc05334550a3e5806f9e6c8705c38bc Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 14:36:08 +0300 Subject: [PATCH 04/44] typing --- cantok/tokens/abstract/abstract_token.py | 6 +++--- cantok/tokens/timeout_token.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index 4dfd361..7d5c951 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -2,7 +2,7 @@ from abc import ABC, abstractmethod from threading import RLock from typing import Tuple, List, Dict, Awaitable, Optional, Union, Any - +from collections.abc import Iterable from cantok.errors import CancellationError from cantok.tokens.abstract.cancel_cause import CancelCause @@ -79,9 +79,9 @@ def __add__(self, item: 'AbstractToken') -> 'AbstractToken': def __bool__(self) -> bool: return self.keep_on() - def filter_tokens(self, tokens: Tuple['AbstractToken', ...]) -> List['AbstractToken']: + def filter_tokens(self, tokens: Iterable['AbstractToken']) -> List['AbstractToken']: from cantok import DefaultToken - + result: List[AbstractToken] = [] for token in tokens: diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index 18280be..ca9252c 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -1,6 +1,6 @@ from time import monotonic_ns, perf_counter - from typing import Union, Callable, Tuple, List, Dict, Any +from collections.abc import Iterable from cantok import AbstractToken from cantok import ConditionToken @@ -33,7 +33,7 @@ def function() -> bool: super().__init__(function, *tokens, cancelled=cancelled) - def filter_tokens(self, tokens: Tuple['AbstractToken', ...]) -> List['AbstractToken']: + def filter_tokens(self, tokens: Iterable[AbstractToken]) -> List[AbstractToken]: result: List[AbstractToken] = [] for token in tokens: From c6ddf46a7d1b40a30389a13e40108d0005219fbd Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 14:38:22 +0300 Subject: [PATCH 05/44] timeout in a test --- tests/units/tokens/test_timeout_token.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index a5dfe75..b9820a1 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -317,7 +317,7 @@ def test_timeout_is_more_important_than_cache(): assert report.from_token is inner_token assert report.cause == CancelCause.CANCELLED - sleep(sleep_time * 10) + sleep(sleep_time * 15) for report in token.get_report(True), token.get_report(False): assert report is not None From 19cac44c51cf83619a2c849502c42c04b13025e9 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 14:43:24 +0300 Subject: [PATCH 06/44] no extra imports --- cantok/tokens/abstract/abstract_token.py | 2 +- cantok/tokens/timeout_token.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index 7d5c951..4261612 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -1,7 +1,7 @@ from sys import getrefcount from abc import ABC, abstractmethod from threading import RLock -from typing import Tuple, List, Dict, Awaitable, Optional, Union, Any +from typing import List, Dict, Awaitable, Optional, Union, Any from collections.abc import Iterable from cantok.errors import CancellationError diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index ca9252c..30376eb 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -1,5 +1,5 @@ from time import monotonic_ns, perf_counter -from typing import Union, Callable, Tuple, List, Dict, Any +from typing import Union, Callable, List, Dict, Any from collections.abc import Iterable from cantok import AbstractToken From 6ec807bf8ec7b1d6275be06e768ca2d7bfdcca44 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 15:05:48 +0300 Subject: [PATCH 07/44] fucking stupid tuping --- cantok/tokens/timeout_token.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index 30376eb..244f171 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -1,12 +1,18 @@ from time import monotonic_ns, perf_counter -from typing import Union, Callable, List, Dict, Any +from typing import TypeAlias, Union, Callable, List, Dict, Any from collections.abc import Iterable +import sys from cantok import AbstractToken from cantok import ConditionToken from cantok.errors import TimeoutCancellationError +if sys.version_info >= (3, 8): + IterableWithTokens: TypeAlias = Iterable[AbstractToken] # pragma: no cover +else: + IterableWithTokens = Iterable # pragma: no cover + class TimeoutToken(ConditionToken): exception = TimeoutCancellationError @@ -33,7 +39,7 @@ def function() -> bool: super().__init__(function, *tokens, cancelled=cancelled) - def filter_tokens(self, tokens: Iterable[AbstractToken]) -> List[AbstractToken]: + def filter_tokens(self, tokens: IterableWithTokens) -> List[AbstractToken]: result: List[AbstractToken] = [] for token in tokens: From 4e8d40bc64262cd4566b06ff66b54271eefb5758 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 15:06:55 +0300 Subject: [PATCH 08/44] fucking stupid tuping --- cantok/tokens/abstract/abstract_token.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index 4261612..184c2a5 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -1,7 +1,8 @@ +import sys from sys import getrefcount from abc import ABC, abstractmethod from threading import RLock -from typing import List, Dict, Awaitable, Optional, Union, Any +from typing import TypeAlias, List, Dict, Awaitable, Optional, Union, Any from collections.abc import Iterable from cantok.errors import CancellationError @@ -10,6 +11,11 @@ from cantok.tokens.abstract.coroutine_wrapper import WaitCoroutineWrapper +if sys.version_info >= (3, 8): + IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # pragma: no cover +else: + IterableWithTokens = Iterable # pragma: no cover + class AbstractToken(ABC): exception = CancellationError rollback_if_nondirect_polling = False @@ -79,7 +85,7 @@ def __add__(self, item: 'AbstractToken') -> 'AbstractToken': def __bool__(self) -> bool: return self.keep_on() - def filter_tokens(self, tokens: Iterable['AbstractToken']) -> List['AbstractToken']: + def filter_tokens(self, tokens: IterableWithTokens) -> List['AbstractToken']: from cantok import DefaultToken result: List[AbstractToken] = [] From db206cb6946319316f2c814c4f6cdc0902efa8ae Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 15:10:11 +0300 Subject: [PATCH 09/44] fucking stupid tuping --- cantok/tokens/abstract/abstract_token.py | 7 ++++++- pyproject.toml | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index 184c2a5..db3d517 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -2,9 +2,14 @@ from sys import getrefcount from abc import ABC, abstractmethod from threading import RLock -from typing import TypeAlias, List, Dict, Awaitable, Optional, Union, Any +from typing import List, Dict, Awaitable, Optional, Union, Any from collections.abc import Iterable +try: + from typing import TypeAlias +except ImportError: # pragma: no cover + from typing_extensions import TypeAlias + from cantok.errors import CancellationError from cantok.tokens.abstract.cancel_cause import CancelCause from cantok.tokens.abstract.report import CancellationReport diff --git a/pyproject.toml b/pyproject.toml index f8ff70f..75cc91b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,6 +11,9 @@ authors = [ description = 'Implementation of the "Cancellation Token" pattern' readme = "README.md" requires-python = ">=3.7" +dependencies = [ + 'typing_extensions ; python_version <= "3.9"', +] classifiers = [ "Operating System :: OS Independent", 'Operating System :: MacOS :: MacOS X', From 877f2d64419e1860c62aa4bc10a165f138222fb5 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 15:13:38 +0300 Subject: [PATCH 10/44] fucking stupid tuping --- cantok/tokens/timeout_token.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index 244f171..8b2f41d 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -1,8 +1,13 @@ from time import monotonic_ns, perf_counter -from typing import TypeAlias, Union, Callable, List, Dict, Any +from typing import Union, Callable, List, Dict, Any from collections.abc import Iterable import sys +try: + from typing import TypeAlias +except ImportError: # pragma: no cover + from typing_extensions import TypeAlias + from cantok import AbstractToken from cantok import ConditionToken from cantok.errors import TimeoutCancellationError From 1cbf57965065c673481c9114eae3d9fc9d510055 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 15:18:08 +0300 Subject: [PATCH 11/44] fucking stupid tuping --- cantok/tokens/abstract/abstract_token.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index db3d517..a1f7839 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -16,7 +16,7 @@ from cantok.tokens.abstract.coroutine_wrapper import WaitCoroutineWrapper -if sys.version_info >= (3, 8): +if sys.version_info > (3, 8): IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # pragma: no cover else: IterableWithTokens = Iterable # pragma: no cover From 33311c981de0ae515b3eadb248a81d970960891f Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 15:21:37 +0300 Subject: [PATCH 12/44] fucking stupid tuping --- cantok/tokens/abstract/abstract_token.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index a1f7839..a438724 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -15,6 +15,10 @@ from cantok.tokens.abstract.report import CancellationReport from cantok.tokens.abstract.coroutine_wrapper import WaitCoroutineWrapper +if sys.version_info > (3, 9): + from typing import TypeAlias +else: # pragma: no cover + from typing_extensions import TypeAlias if sys.version_info > (3, 8): IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # pragma: no cover From c508420ae8267b3d19d2b6b83d7dd5b0b66da6e7 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 15:47:38 +0300 Subject: [PATCH 13/44] fucking stupid tuping --- cantok/tokens/abstract/abstract_token.py | 16 +--------------- cantok/tokens/timeout_token.py | 11 +---------- cantok/types.py | 13 +++++++++++++ 3 files changed, 15 insertions(+), 25 deletions(-) create mode 100644 cantok/types.py diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index a438724..55e594c 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -3,27 +3,13 @@ from abc import ABC, abstractmethod from threading import RLock from typing import List, Dict, Awaitable, Optional, Union, Any -from collections.abc import Iterable - -try: - from typing import TypeAlias -except ImportError: # pragma: no cover - from typing_extensions import TypeAlias from cantok.errors import CancellationError from cantok.tokens.abstract.cancel_cause import CancelCause from cantok.tokens.abstract.report import CancellationReport from cantok.tokens.abstract.coroutine_wrapper import WaitCoroutineWrapper +from cantok.types import IterableWithTokens -if sys.version_info > (3, 9): - from typing import TypeAlias -else: # pragma: no cover - from typing_extensions import TypeAlias - -if sys.version_info > (3, 8): - IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # pragma: no cover -else: - IterableWithTokens = Iterable # pragma: no cover class AbstractToken(ABC): exception = CancellationError diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index 8b2f41d..1a5e13f 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -3,21 +3,12 @@ from collections.abc import Iterable import sys -try: - from typing import TypeAlias -except ImportError: # pragma: no cover - from typing_extensions import TypeAlias - from cantok import AbstractToken from cantok import ConditionToken from cantok.errors import TimeoutCancellationError +from cantok.types import IterableWithTokens -if sys.version_info >= (3, 8): - IterableWithTokens: TypeAlias = Iterable[AbstractToken] # pragma: no cover -else: - IterableWithTokens = Iterable # pragma: no cover - class TimeoutToken(ConditionToken): exception = TimeoutCancellationError diff --git a/cantok/types.py b/cantok/types.py new file mode 100644 index 0000000..01d0a47 --- /dev/null +++ b/cantok/types.py @@ -0,0 +1,13 @@ +import sys +from collections.abc import Iterable + + +if sys.version_info > (3, 9): + from typing import TypeAlias # pragma: no cover +else: + from typing_extensions import TypeAlias # pragma: no cover + +if sys.version_info > (3, 8): + IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # type: ignore[name-defined] +else: + IterableWithTokens = Iterable # pragma: no cover From e011e974a5fee10afc92aa5bbf59984126383d16 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 15:50:50 +0300 Subject: [PATCH 14/44] fucking stupid tuping --- cantok/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cantok/types.py b/cantok/types.py index 01d0a47..c665267 100644 --- a/cantok/types.py +++ b/cantok/types.py @@ -8,6 +8,6 @@ from typing_extensions import TypeAlias # pragma: no cover if sys.version_info > (3, 8): - IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # type: ignore[name-defined] + IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # type: ignore[name-defined, unused-ignore] else: IterableWithTokens = Iterable # pragma: no cover From 82664e2922270a4afaba7414f2357f97b8c6fed8 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 16:01:12 +0300 Subject: [PATCH 15/44] fucking stupid tuping --- cantok/types.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cantok/types.py b/cantok/types.py index c665267..ed1ed49 100644 --- a/cantok/types.py +++ b/cantok/types.py @@ -2,12 +2,12 @@ from collections.abc import Iterable -if sys.version_info > (3, 9): +if sys.version_info >= (3, 10): from typing import TypeAlias # pragma: no cover else: from typing_extensions import TypeAlias # pragma: no cover -if sys.version_info > (3, 8): +if sys.version_info >= (3, 9): IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # type: ignore[name-defined, unused-ignore] else: IterableWithTokens = Iterable # pragma: no cover From 7a7e2a227ecfca7073131261f103151b029b7d41 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 16:04:37 +0300 Subject: [PATCH 16/44] coverage ignore comment --- cantok/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cantok/types.py b/cantok/types.py index ed1ed49..ff43e03 100644 --- a/cantok/types.py +++ b/cantok/types.py @@ -8,6 +8,6 @@ from typing_extensions import TypeAlias # pragma: no cover if sys.version_info >= (3, 9): - IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # type: ignore[name-defined, unused-ignore] + IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # type: ignore[name-defined, unused-ignore] # pragma: no cover else: IterableWithTokens = Iterable # pragma: no cover From e353c39a00b59d2d2c88ed66068abaece8e668ba Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 16:10:50 +0300 Subject: [PATCH 17/44] prints in a test --- tests/units/tokens/test_timeout_token.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index b9820a1..baef40b 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -388,6 +388,8 @@ def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_not_same_mo def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_temp_not_monotonic_timeout_token_with_same_monotonic_flag(timeout_for_equal_or_bigger_token, addictional_kwargs): token = TimeoutToken(1, **addictional_kwargs) + TimeoutToken(timeout_for_equal_or_bigger_token, **addictional_kwargs) + print(token.deadline) + print(token.tokens[0].deadline if len(token.tokens) > 0 else None) assert isinstance(token, TimeoutToken) assert token.timeout == 1 assert len(token.tokens) == 0 From f0305dceff13ac496e01e7449c9e3a790c42e640 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 16:15:25 +0300 Subject: [PATCH 18/44] timeout in a test --- tests/units/tokens/test_timeout_token.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index baef40b..7dbfb8d 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -307,7 +307,7 @@ def test_not_quasitemp_timeout_token_plus_not_temp_simple_token_reverse(): def test_timeout_is_more_important_than_cache(): - sleep_time = 0.0001 + sleep_time = 0.001 inner_token = SimpleToken(cancelled=True) token = TimeoutToken(sleep_time, inner_token) From 99084791200de1cad0e57c6ce85733434efadcb3 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 16:19:11 +0300 Subject: [PATCH 19/44] print in a test --- tests/units/tokens/test_timeout_token.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index 7dbfb8d..bf9b72f 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -390,6 +390,7 @@ def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_tem print(token.deadline) print(token.tokens[0].deadline if len(token.tokens) > 0 else None) + print(token) assert isinstance(token, TimeoutToken) assert token.timeout == 1 assert len(token.tokens) == 0 From 24f5a72d45aa35c84c91e812c708a6e05864a267 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 16:52:12 +0300 Subject: [PATCH 20/44] print in a test --- tests/units/tokens/test_timeout_token.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index bf9b72f..dd66f10 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -390,7 +390,7 @@ def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_tem print(token.deadline) print(token.tokens[0].deadline if len(token.tokens) > 0 else None) - print(token) + print(repr(token)) assert isinstance(token, TimeoutToken) assert token.timeout == 1 assert len(token.tokens) == 0 From bece4d3d9876d128b5f2632efaa9bf04f7f26844 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 16:56:11 +0300 Subject: [PATCH 21/44] timeout checking in timeout token --- cantok/tokens/timeout_token.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index 1a5e13f..ef8194a 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -39,7 +39,7 @@ def filter_tokens(self, tokens: IterableWithTokens) -> List[AbstractToken]: result: List[AbstractToken] = [] for token in tokens: - if isinstance(token, TimeoutToken) and token.monotonic == self.monotonic and self.deadline < token.deadline: + if isinstance(token, TimeoutToken) and token.monotonic == self.monotonic and self.deadline <= token.deadline: result.extend(token.tokens) else: result.append(token) From 304597a3a53847007ba62d5c81a3e68f1e33a22a Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 19:03:58 +0300 Subject: [PATCH 22/44] empty lines --- cantok/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cantok/types.py b/cantok/types.py index ff43e03..a0bc38d 100644 --- a/cantok/types.py +++ b/cantok/types.py @@ -1,12 +1,12 @@ import sys from collections.abc import Iterable - if sys.version_info >= (3, 10): from typing import TypeAlias # pragma: no cover else: from typing_extensions import TypeAlias # pragma: no cover + if sys.version_info >= (3, 9): IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # type: ignore[name-defined, unused-ignore] # pragma: no cover else: From f0c1f81e91bc6b5640c6601768233a4e42043912 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 19:04:55 +0300 Subject: [PATCH 23/44] fucking stupid tuping --- cantok/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cantok/types.py b/cantok/types.py index a0bc38d..d5fcd9e 100644 --- a/cantok/types.py +++ b/cantok/types.py @@ -10,4 +10,4 @@ if sys.version_info >= (3, 9): IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # type: ignore[name-defined, unused-ignore] # pragma: no cover else: - IterableWithTokens = Iterable # pragma: no cover + IterableWithTokens = Iterable['AbstractToken'] # pragma: no cover From e65efdce269d7845b5002707b15304c2127882aa Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 19:07:05 +0300 Subject: [PATCH 24/44] fucking stupid typing --- cantok/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cantok/types.py b/cantok/types.py index d5fcd9e..a0bc38d 100644 --- a/cantok/types.py +++ b/cantok/types.py @@ -10,4 +10,4 @@ if sys.version_info >= (3, 9): IterableWithTokens: TypeAlias = Iterable['AbstractToken'] # type: ignore[name-defined, unused-ignore] # pragma: no cover else: - IterableWithTokens = Iterable['AbstractToken'] # pragma: no cover + IterableWithTokens = Iterable # pragma: no cover From 290370fa6f693653eb7137bcfad9b3979eae352e Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 19:11:19 +0300 Subject: [PATCH 25/44] fucking stupid typing --- cantok/tokens/abstract/abstract_token.py | 2 +- cantok/tokens/timeout_token.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index 55e594c..fc892f6 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -80,7 +80,7 @@ def __add__(self, item: 'AbstractToken') -> 'AbstractToken': def __bool__(self) -> bool: return self.keep_on() - def filter_tokens(self, tokens: IterableWithTokens) -> List['AbstractToken']: + def filter_tokens(self, tokens: IterableWithTokens) -> List['AbstractToken']: # type: ignore[type-arg] from cantok import DefaultToken result: List[AbstractToken] = [] diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index ef8194a..7664411 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -35,7 +35,7 @@ def function() -> bool: super().__init__(function, *tokens, cancelled=cancelled) - def filter_tokens(self, tokens: IterableWithTokens) -> List[AbstractToken]: + def filter_tokens(self, tokens: IterableWithTokens) -> List[AbstractToken]: # type: ignore[type-arg] result: List[AbstractToken] = [] for token in tokens: From 79f3b136123acb16e7f1927dbedd6026b9e9685b Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 19:14:12 +0300 Subject: [PATCH 26/44] no extra imports --- cantok/tokens/abstract/abstract_token.py | 1 - cantok/tokens/timeout_token.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index fc892f6..7724341 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -1,4 +1,3 @@ -import sys from sys import getrefcount from abc import ABC, abstractmethod from threading import RLock diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index 7664411..98e21b5 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -1,7 +1,5 @@ from time import monotonic_ns, perf_counter from typing import Union, Callable, List, Dict, Any -from collections.abc import Iterable -import sys from cantok import AbstractToken from cantok import ConditionToken From 388de7b251047e6021d27b8fda14659d9968b6ba Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 19:43:33 +0300 Subject: [PATCH 27/44] timeout token sum optimization when the bigger deadline at the left side --- cantok/tokens/abstract/abstract_token.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index 7724341..63ee54e 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -53,11 +53,16 @@ def __add__(self, item: 'AbstractToken') -> 'AbstractToken': if not isinstance(item, AbstractToken): raise TypeError('Cancellation Token can only be combined with another Cancellation Token.') - from cantok import SimpleToken, DefaultToken + from cantok import SimpleToken, DefaultToken, TimeoutToken nested_tokens = [] container_token: Optional[AbstractToken] = None + if isinstance(self, TimeoutToken) and isinstance(item, TimeoutToken): + if self.monotonic == item.monotonic and self.deadline >= item.deadline and getrefcount(item) < 6: + item.tokens.extend(self.tokens) + return item + for token in self, item: if token._cancelled: return SimpleToken(cancelled=True) From 24abdca11107d311e1d15835b1e9c9f0b30b0036 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 19:45:13 +0300 Subject: [PATCH 28/44] no extra prints --- tests/units/tokens/test_timeout_token.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index dd66f10..0371ae3 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -205,8 +205,6 @@ async def runner(): asyncio.run(runner()) finish_time = perf_counter() - print(finish_time - start_time) - assert (finish_time - start_time) < (sleep_duration * number_of_tokens) @@ -388,9 +386,6 @@ def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_not_same_mo def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_temp_not_monotonic_timeout_token_with_same_monotonic_flag(timeout_for_equal_or_bigger_token, addictional_kwargs): token = TimeoutToken(1, **addictional_kwargs) + TimeoutToken(timeout_for_equal_or_bigger_token, **addictional_kwargs) - print(token.deadline) - print(token.tokens[0].deadline if len(token.tokens) > 0 else None) - print(repr(token)) assert isinstance(token, TimeoutToken) assert token.timeout == 1 assert len(token.tokens) == 0 From 4ce8e5da2add1467ed79d0ad10df5b6469004730 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 19:58:43 +0300 Subject: [PATCH 29/44] fix with filled first timeout token --- cantok/tokens/abstract/abstract_token.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index 63ee54e..dd90909 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -59,7 +59,7 @@ def __add__(self, item: 'AbstractToken') -> 'AbstractToken': container_token: Optional[AbstractToken] = None if isinstance(self, TimeoutToken) and isinstance(item, TimeoutToken): - if self.monotonic == item.monotonic and self.deadline >= item.deadline and getrefcount(item) < 6: + if self.monotonic == item.monotonic and self.deadline >= item.deadline and getrefcount(self) < 4: item.tokens.extend(self.tokens) return item From c4116cdcca2be1be3ff83330c5d03026707356d1 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 20:08:38 +0300 Subject: [PATCH 30/44] fix with filled first timeout token --- cantok/tokens/abstract/abstract_token.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index dd90909..01ac617 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -60,8 +60,14 @@ def __add__(self, item: 'AbstractToken') -> 'AbstractToken': if isinstance(self, TimeoutToken) and isinstance(item, TimeoutToken): if self.monotonic == item.monotonic and self.deadline >= item.deadline and getrefcount(self) < 4: - item.tokens.extend(self.tokens) - return item + if getrefcount(item) < 4: + item.tokens.extend(self.tokens) + return item + else: + if self.tokens: + return SimpleToken(item, *(self.tokens)) + else: + return item for token in self, item: if token._cancelled: From 432336c5b81b95dbfe4941719361bcba326d7485 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 20:10:33 +0300 Subject: [PATCH 31/44] all old tests fixed --- .../units/tokens/abstract/test_abstract_token.py | 12 ++++++++---- tests/units/tokens/test_timeout_token.py | 15 ++++----------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/tests/units/tokens/abstract/test_abstract_token.py b/tests/units/tokens/abstract/test_abstract_token.py index d4f285d..b789bd5 100644 --- a/tests/units/tokens/abstract/test_abstract_token.py +++ b/tests/units/tokens/abstract/test_abstract_token.py @@ -229,10 +229,14 @@ def test_add_temp_token_and_not_temp_token(first_token_class, second_token_class second_token = second_token_class(*second_arguments) tokens_sum = first_token_class(*first_arguments) + second_token - assert isinstance(tokens_sum, first_token_class) - assert len(tokens_sum.tokens) == 1 - assert isinstance(tokens_sum.tokens[0], second_token_class) - assert len(tokens_sum.tokens[0].tokens) == 0 + if first_token_class is TimeoutToken and second_token_class is TimeoutToken: + assert isinstance(tokens_sum, TimeoutToken) + assert len(tokens_sum.tokens) == 0 + else: + assert isinstance(tokens_sum, first_token_class) + assert len(tokens_sum.tokens) == 1 + assert isinstance(tokens_sum.tokens[0], second_token_class) + assert len(tokens_sum.tokens[0].tokens) == 0 @pytest.mark.parametrize( diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index 0371ae3..2368244 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -341,11 +341,8 @@ def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_same_monoto token = TimeoutToken(2, **addictional_kwargs) + TimeoutToken(1, **addictional_kwargs) assert isinstance(token, TimeoutToken) - assert token.timeout == 2 - assert len(token.tokens) == 1 - assert len(token.tokens[0].tokens) == 0 - assert isinstance(token.tokens[0], TimeoutToken) - assert token.tokens[0].timeout == 1 + assert token.timeout == 1 + assert len(token.tokens) == 0 @pytest.mark.parametrize( @@ -514,12 +511,8 @@ def test_bigger_temp_timeout_token_plus_less_timeout_token_with_same_monotonic_f token = TimeoutToken(2, **addictional_kwargs) + right_timeout_token assert isinstance(token, TimeoutToken) - assert token.timeout == 2 - assert len(token.tokens) == 1 - assert len(token.tokens[0].tokens) == 0 - assert isinstance(token.tokens[0], TimeoutToken) - assert token.tokens[0].timeout == 1 - assert token.tokens[0] is right_timeout_token + assert token.timeout == 1 + assert len(token.tokens) == 0 @pytest.mark.parametrize( From 2d13e5d566ab326203693125d517de1ecb0c0c05 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 20:25:11 +0300 Subject: [PATCH 32/44] fixed a bug with deleting of not temp tokens --- cantok/tokens/timeout_token.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index 98e21b5..edfd588 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -1,4 +1,5 @@ from time import monotonic_ns, perf_counter +from sys import getrefcount from typing import Union, Callable, List, Dict, Any from cantok import AbstractToken @@ -37,7 +38,7 @@ def filter_tokens(self, tokens: IterableWithTokens) -> List[AbstractToken]: # t result: List[AbstractToken] = [] for token in tokens: - if isinstance(token, TimeoutToken) and token.monotonic == self.monotonic and self.deadline <= token.deadline: + if isinstance(token, TimeoutToken) and token.monotonic == self.monotonic and self.deadline <= token.deadline and getrefcount(token) < 7: result.extend(token.tokens) else: result.append(token) From 9efc5460c528be6ec5b2f9280b9ed574f7e1d177 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 20:27:25 +0300 Subject: [PATCH 33/44] an old test fixed --- tests/units/tokens/test_timeout_token.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index 2368244..7d96231 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -551,7 +551,10 @@ def test_less_temp_not_monotonic_timeout_token_plus_bigger_not_monotonic_timeout assert isinstance(token, TimeoutToken) assert token.timeout == 1 - assert len(token.tokens) == 0 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert token.tokens[0].timeout == 2 + assert token.tokens[0] is right_timeout_token @pytest.mark.parametrize( From 0b6254f7a869c3352088fa48a04b65ce53d8484e Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 21:08:04 +0300 Subject: [PATCH 34/44] fix of sums in some rare cases --- cantok/tokens/abstract/abstract_token.py | 4 ++-- cantok/tokens/timeout_token.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index 01ac617..94fb049 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -84,13 +84,13 @@ def __add__(self, item: 'AbstractToken') -> 'AbstractToken': if container_token is None: return SimpleToken(*nested_tokens) else: - container_token.tokens.extend(container_token.filter_tokens(nested_tokens)) + container_token.tokens.extend(container_token.filter_tokens(nested_tokens, expected_refcount=6)) return container_token def __bool__(self) -> bool: return self.keep_on() - def filter_tokens(self, tokens: IterableWithTokens) -> List['AbstractToken']: # type: ignore[type-arg] + def filter_tokens(self, tokens: IterableWithTokens, expected_refcount: int = 0) -> List['AbstractToken']: # type: ignore[type-arg] from cantok import DefaultToken result: List[AbstractToken] = [] diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index edfd588..d76a028 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -34,11 +34,11 @@ def function() -> bool: super().__init__(function, *tokens, cancelled=cancelled) - def filter_tokens(self, tokens: IterableWithTokens) -> List[AbstractToken]: # type: ignore[type-arg] + def filter_tokens(self, tokens: IterableWithTokens, expected_refcount: int = 7) -> List[AbstractToken]: # type: ignore[type-arg] result: List[AbstractToken] = [] for token in tokens: - if isinstance(token, TimeoutToken) and token.monotonic == self.monotonic and self.deadline <= token.deadline and getrefcount(token) < 7: + if isinstance(token, TimeoutToken) and token.monotonic == self.monotonic and self.deadline <= token.deadline and getrefcount(token) < expected_refcount: result.extend(token.tokens) else: result.append(token) From cff1d125d2f877a6eb296fc688dd890838cfa683 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Thu, 8 Aug 2024 22:39:43 +0300 Subject: [PATCH 35/44] some fixes in timeout tokens sums + tests --- cantok/tokens/abstract/abstract_token.py | 15 +- cantok/tokens/timeout_token.py | 11 - .../tokens/abstract/test_abstract_token.py | 12 +- tests/units/tokens/test_simple_token.py | 4 +- tests/units/tokens/test_timeout_token.py | 478 +++++++++++++++++- 5 files changed, 493 insertions(+), 27 deletions(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index 94fb049..453f807 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -58,16 +58,25 @@ def __add__(self, item: 'AbstractToken') -> 'AbstractToken': nested_tokens = [] container_token: Optional[AbstractToken] = None - if isinstance(self, TimeoutToken) and isinstance(item, TimeoutToken): - if self.monotonic == item.monotonic and self.deadline >= item.deadline and getrefcount(self) < 4: + if isinstance(self, TimeoutToken) and isinstance(item, TimeoutToken) and self.monotonic == item.monotonic: + if self.deadline >= item.deadline and getrefcount(self) < 4: if getrefcount(item) < 4: item.tokens.extend(self.tokens) return item else: if self.tokens: - return SimpleToken(item, *(self.tokens)) + return SimpleToken(*(self.tokens), item) else: return item + elif self.deadline < item.deadline and getrefcount(item) < 4: + if getrefcount(self) < 4: + self.tokens.extend(item.tokens) + return self + else: + if item.tokens: + return SimpleToken(*(item.tokens), self) + else: + return self for token in self, item: if token._cancelled: diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index d76a028..1bbe4a4 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -34,17 +34,6 @@ def function() -> bool: super().__init__(function, *tokens, cancelled=cancelled) - def filter_tokens(self, tokens: IterableWithTokens, expected_refcount: int = 7) -> List[AbstractToken]: # type: ignore[type-arg] - result: List[AbstractToken] = [] - - for token in tokens: - if isinstance(token, TimeoutToken) and token.monotonic == self.monotonic and self.deadline <= token.deadline and getrefcount(token) < expected_refcount: - result.extend(token.tokens) - else: - result.append(token) - - return super().filter_tokens(result) - def text_representation_of_superpower(self) -> str: return str(self.timeout) diff --git a/tests/units/tokens/abstract/test_abstract_token.py b/tests/units/tokens/abstract/test_abstract_token.py index b789bd5..800e115 100644 --- a/tests/units/tokens/abstract/test_abstract_token.py +++ b/tests/units/tokens/abstract/test_abstract_token.py @@ -203,10 +203,14 @@ def test_add_not_temp_token_and_temp_token(first_token_class, second_token_class first_token = first_token_class(*first_arguments) tokens_sum = first_token + second_token_class(*second_arguments) - assert isinstance(tokens_sum, second_token_class) - assert len(tokens_sum.tokens) == 1 - assert isinstance(tokens_sum.tokens[0], first_token_class) - assert len(tokens_sum.tokens[0].tokens) == 0 + if first_token_class is TimeoutToken and second_token_class is TimeoutToken: + assert tokens_sum is first_token + assert not tokens_sum.tokens + else: + assert isinstance(tokens_sum, second_token_class) + assert len(tokens_sum.tokens) == 1 + assert isinstance(tokens_sum.tokens[0], first_token_class) + assert len(tokens_sum.tokens[0].tokens) == 0 @pytest.mark.parametrize( diff --git a/tests/units/tokens/test_simple_token.py b/tests/units/tokens/test_simple_token.py index 6763a92..101635a 100644 --- a/tests/units/tokens/test_simple_token.py +++ b/tests/units/tokens/test_simple_token.py @@ -196,8 +196,10 @@ def test_sum_of_2_temp_timeout_tokens_throw_right_temp_simple_token(): token = TimeoutToken(1) + SimpleToken(TimeoutToken(2)) assert isinstance(token, TimeoutToken) - assert len(token.tokens) == 0 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 assert token.timeout == 1 + assert token.tokens[0].timeout == 2 def test_sum_of_2_temp_timeout_tokens_throw_left_temp_simple_token(): diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index 7d96231..3dbda67 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -4,7 +4,7 @@ import pytest from cantok.tokens.abstract.abstract_token import CancelCause, CancellationReport -from cantok import SimpleToken, TimeoutToken, TimeoutCancellationError +from cantok import SimpleToken, TimeoutToken, ConditionToken, TimeoutCancellationError @pytest.mark.parametrize( @@ -430,7 +430,11 @@ def test_bigger_timeout_token_plus_less_temp_timeout_token_with_same_monotonic_f assert isinstance(token, TimeoutToken) assert token is not left_timeout_token assert token.timeout == 1 - assert len(token.tokens) == 0 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == 2 + assert token.tokens[0] is left_timeout_token @pytest.mark.parametrize( @@ -468,12 +472,8 @@ def test_less_not_monotonic_timeout_token_plus_bigger_temp_not_monotonic_timeout token = left_timeout_token + TimeoutToken(2, **addictional_kwargs) assert isinstance(token, TimeoutToken) - assert token.timeout == 2 - assert len(token.tokens) == 1 - assert len(token.tokens[0].tokens) == 0 - assert isinstance(token.tokens[0], TimeoutToken) - assert token.tokens[0].timeout == 1 - assert token.tokens[0] is left_timeout_token + assert token.timeout == 1 + assert len(token.tokens) == 0 @pytest.mark.parametrize( @@ -697,3 +697,465 @@ def test_less_or_equal_not_monotonic_timeout_token_plus_bigger_or_equal_not_mono assert token.tokens[1].timeout == timeout_for_equal_or_bigger_token assert token.tokens[0] is left assert token.tokens[1] is right + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right(addictional_kwargs): + token = TimeoutToken(2, **addictional_kwargs) + TimeoutToken(1, ConditionToken(lambda: True), **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 1 + assert isinstance(token.tokens[0], ConditionToken) + assert len(token.tokens[0].tokens) == 0 + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right(left_addictional_kwargs, right_addictional_kwargs): + token = TimeoutToken(2, **left_addictional_kwargs) + TimeoutToken(1, ConditionToken(lambda: True), **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 2 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 1 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == 1 + assert isinstance(token.tokens[0].tokens[0], ConditionToken) + assert len(token.tokens[0].tokens[0].tokens) == 0 + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_temp_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right(timeout_for_equal_or_bigger_token, addictional_kwargs): + token = TimeoutToken(1, **addictional_kwargs) + TimeoutToken(timeout_for_equal_or_bigger_token, ConditionToken(lambda: True), **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], ConditionToken) + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_temp_not_monotonic_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right(timeout_for_equal_or_bigger_token, left_addictional_kwargs, right_addictional_kwargs): + token = TimeoutToken(1, **left_addictional_kwargs) + TimeoutToken(timeout_for_equal_or_bigger_token, ConditionToken(lambda: True), **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 1 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == timeout_for_equal_or_bigger_token + assert isinstance(token.tokens[0].tokens[0], ConditionToken) + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_timeout_token_plus_less_temp_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right(addictional_kwargs): + left_timeout_token = TimeoutToken(2, **addictional_kwargs) + token = left_timeout_token + TimeoutToken(1, ConditionToken(lambda: True), **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token is not left_timeout_token + assert token.timeout == 1 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert isinstance(token.tokens[0], ConditionToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[1].timeout == 2 + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_timeout_token_plus_less_temp_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right(left_addictional_kwargs, right_addictional_kwargs): + left_timeout_token = TimeoutToken(2, **left_addictional_kwargs) + token = left_timeout_token + TimeoutToken(1, ConditionToken(lambda: True), **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert isinstance(token.tokens[0], ConditionToken) + assert token.tokens[0] is not left_timeout_token + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[1].timeout == 2 + assert token.tokens[1] is left_timeout_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_not_monotonic_timeout_token_plus_bigger_temp_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right(addictional_kwargs): + left_timeout_token = TimeoutToken(1, **addictional_kwargs) + token = left_timeout_token + TimeoutToken(2, ConditionToken(lambda: True), **addictional_kwargs) + + assert isinstance(token, SimpleToken) + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert isinstance(token.tokens[0], ConditionToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[1].timeout == 1 + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_not_monotonic_timeout_token_plus_bigger_temp_not_monotonic_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right(left_addictional_kwargs, right_addictional_kwargs): + left_timeout_token = TimeoutToken(1, **left_addictional_kwargs) + token = left_timeout_token + TimeoutToken(2, ConditionToken(lambda: True), **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 2 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert isinstance(token.tokens[0], ConditionToken) + assert token.tokens[0] is not left_timeout_token + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[1].timeout == 1 + assert token.tokens[1] is left_timeout_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_temp_timeout_token_plus_less_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right(addictional_kwargs): + right_timeout_token = TimeoutToken(1, ConditionToken(lambda: True), **addictional_kwargs) + token = TimeoutToken(2, **addictional_kwargs) + right_timeout_token + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], ConditionToken) + assert token is right_timeout_token + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_temp_timeout_token_plus_less_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right(left_addictional_kwargs, right_addictional_kwargs): + right_timeout_token = TimeoutToken(1, ConditionToken(lambda: True), **right_addictional_kwargs) + token = TimeoutToken(2, **left_addictional_kwargs) + right_timeout_token + + assert isinstance(token, TimeoutToken) + assert token.timeout == 2 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[0].tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == 1 + assert token.tokens[0] is right_timeout_token + assert isinstance(token.tokens[0].tokens[0], ConditionToken) + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_temp_not_monotonic_timeout_token_plus_bigger_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right(addictional_kwargs): + right_timeout_token = TimeoutToken(2, ConditionToken(lambda: True), **addictional_kwargs) + token = TimeoutToken(1, **addictional_kwargs) + right_timeout_token + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[0].tokens[0].tokens) == 0 + assert token.tokens[0].timeout == 2 + assert token.tokens[0] is right_timeout_token + assert isinstance(token.tokens[0].tokens[0], ConditionToken) + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_temp_not_monotonic_timeout_token_plus_bigger_not_monotonic_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right(left_addictional_kwargs, right_addictional_kwargs): + right_timeout_token = TimeoutToken(2, ConditionToken(lambda: True), **right_addictional_kwargs) + token = TimeoutToken(1, **left_addictional_kwargs) + right_timeout_token + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[0].tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert token.tokens[0].timeout == 2 + assert token.tokens[0] is right_timeout_token + assert isinstance(token.tokens[0].tokens[0], ConditionToken) + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_timeout_token_plus_less_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right(addictional_kwargs): + left = TimeoutToken(2, **addictional_kwargs) + right = TimeoutToken(1, ConditionToken(lambda: False), **addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[0].timeout == 2 + assert token.tokens[1].timeout == 1 + assert token.tokens[0] is left + assert token.tokens[1] is right + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_timeout_token_plus_less_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right(left_addictional_kwargs, right_addictional_kwargs): + left = TimeoutToken(2, **left_addictional_kwargs) + right = TimeoutToken(1, ConditionToken(lambda: False), **right_addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[0].timeout == 2 + assert token.tokens[1].timeout == 1 + assert token.tokens[0] is left + assert token.tokens[1] is right + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_or_equal_not_monotonic_timeout_token_plus_bigger_or_equal_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right(timeout_for_equal_or_bigger_token, addictional_kwargs): + left = TimeoutToken(1, **addictional_kwargs) + right = TimeoutToken(timeout_for_equal_or_bigger_token, ConditionToken(lambda: False), **addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[0].timeout == 1 + assert token.tokens[1].timeout == timeout_for_equal_or_bigger_token + assert token.tokens[0] is left + assert token.tokens[1] is right + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_or_equal_not_monotonic_timeout_token_plus_bigger_or_equal_not_monotonic_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right(timeout_for_equal_or_bigger_token, left_addictional_kwargs, right_addictional_kwargs): + left = TimeoutToken(1, **left_addictional_kwargs) + right = TimeoutToken(timeout_for_equal_or_bigger_token, ConditionToken(lambda: False), **right_addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[0].timeout == 1 + assert token.tokens[1].timeout == timeout_for_equal_or_bigger_token + assert token.tokens[0] is left + assert token.tokens[1] is right + assert isinstance(token.tokens[1].tokens[0], ConditionToken) From 506a55c85a46067b267d188f44f6290328f0a3ce Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Fri, 9 Aug 2024 00:57:40 +0300 Subject: [PATCH 36/44] new tests --- tests/units/tokens/test_timeout_token.py | 920 +++++++++++++++++++++-- 1 file changed, 862 insertions(+), 58 deletions(-) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index 3dbda67..bc378b2 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -4,7 +4,7 @@ import pytest from cantok.tokens.abstract.abstract_token import CancelCause, CancellationReport -from cantok import SimpleToken, TimeoutToken, ConditionToken, TimeoutCancellationError +from cantok import SimpleToken, TimeoutToken, ConditionToken, CounterToken, TimeoutCancellationError @pytest.mark.parametrize( @@ -699,63 +699,6 @@ def test_less_or_equal_not_monotonic_timeout_token_plus_bigger_or_equal_not_mono assert token.tokens[1] is right - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @pytest.mark.parametrize( ['addictional_kwargs'], [ @@ -1159,3 +1102,864 @@ def test_less_or_equal_not_monotonic_timeout_token_plus_bigger_or_equal_not_mono assert token.tokens[0] is left assert token.tokens[1] is right assert isinstance(token.tokens[1].tokens[0], ConditionToken) + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(addictional_kwargs): + token = TimeoutToken(2, CounterToken(5), **addictional_kwargs) + TimeoutToken(1, ConditionToken(lambda: True), **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert isinstance(token.tokens[0], ConditionToken) + assert isinstance(token.tokens[1], CounterToken) + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(left_addictional_kwargs, right_addictional_kwargs): + token = TimeoutToken(2, CounterToken(5), **left_addictional_kwargs) + TimeoutToken(1, ConditionToken(lambda: True), **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 2 + assert len(token.tokens) == 2 + assert len(token.tokens[1].tokens) == 1 + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[1].timeout == 1 + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], CounterToken) + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_temp_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(timeout_for_equal_or_bigger_token, addictional_kwargs): + token = TimeoutToken(1, CounterToken(5), **addictional_kwargs) + TimeoutToken(timeout_for_equal_or_bigger_token, ConditionToken(lambda: True), **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert isinstance(token.tokens[0], CounterToken) + assert isinstance(token.tokens[1], ConditionToken) + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_temp_not_monotonic_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(timeout_for_equal_or_bigger_token, left_addictional_kwargs, right_addictional_kwargs): + token = TimeoutToken(1, CounterToken(5), **left_addictional_kwargs) + TimeoutToken(timeout_for_equal_or_bigger_token, ConditionToken(lambda: True), **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], CounterToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + assert token.tokens[1].timeout == timeout_for_equal_or_bigger_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_timeout_token_plus_less_temp_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(addictional_kwargs): + left_timeout_token = TimeoutToken(2, CounterToken(5), **addictional_kwargs) + token = left_timeout_token + TimeoutToken(1, ConditionToken(lambda: True), **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token is not left_timeout_token + assert token.tokens[1] is left_timeout_token + assert token.timeout == 1 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], ConditionToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[1].timeout == 2 + assert isinstance(token.tokens[1].tokens[0], CounterToken) + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_timeout_token_plus_less_temp_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(left_addictional_kwargs, right_addictional_kwargs): + left_timeout_token = TimeoutToken(2, CounterToken(5), **left_addictional_kwargs) + token = left_timeout_token + TimeoutToken(1, ConditionToken(lambda: True), **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token is not left_timeout_token + assert token.tokens[1] is left_timeout_token + assert token.timeout == 1 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], ConditionToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[1].timeout == 2 + assert isinstance(token.tokens[1].tokens[0], CounterToken) + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_not_monotonic_timeout_token_plus_bigger_temp_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(addictional_kwargs): + left_timeout_token = TimeoutToken(1, CounterToken(5), **addictional_kwargs) + token = left_timeout_token + TimeoutToken(2, ConditionToken(lambda: True), **addictional_kwargs) + + assert isinstance(token, SimpleToken) + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], ConditionToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[1].timeout == 1 + assert isinstance(token.tokens[1].tokens[0], CounterToken) + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_not_monotonic_timeout_token_plus_bigger_temp_not_monotonic_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(left_addictional_kwargs, right_addictional_kwargs): + left_timeout_token = TimeoutToken(1, CounterToken(5), **left_addictional_kwargs) + token = left_timeout_token + TimeoutToken(2, ConditionToken(lambda: True), **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 2 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], ConditionToken) + assert token.tokens[0] is not left_timeout_token + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[1].timeout == 1 + assert token.tokens[1] is left_timeout_token + assert isinstance(token.tokens[1].tokens[0], CounterToken) + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_temp_timeout_token_plus_less_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(addictional_kwargs): + right_timeout_token = TimeoutToken(1, ConditionToken(lambda: True), **addictional_kwargs) + token = TimeoutToken(2, CounterToken(5), **addictional_kwargs) + right_timeout_token + + assert isinstance(token, SimpleToken) + assert isinstance(token.tokens[0], CounterToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + assert token.tokens[1].timeout == 1 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert token.tokens[1] is right_timeout_token + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_temp_timeout_token_plus_less_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(left_addictional_kwargs, right_addictional_kwargs): + right_timeout_token = TimeoutToken(1, ConditionToken(lambda: True), **right_addictional_kwargs) + token = TimeoutToken(2, CounterToken(5), **left_addictional_kwargs) + right_timeout_token + + assert isinstance(token, TimeoutToken) + assert isinstance(token.tokens[0], CounterToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + assert token.tokens[1].timeout == 1 + assert token.timeout == 2 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert token.tokens[1] is right_timeout_token + assert token is not right_timeout_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_temp_not_monotonic_timeout_token_plus_bigger_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(addictional_kwargs): + right_timeout_token = TimeoutToken(2, ConditionToken(lambda: True), **addictional_kwargs) + token = TimeoutToken(1, CounterToken(5), **addictional_kwargs) + right_timeout_token + + TimeoutToken(1, CounterToken(5), TimeoutToken(2, ConditionToken(lambda: True))) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert token.timeout == 1 + assert token.tokens[1].timeout == 2 + assert token.tokens[1] is right_timeout_token + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + assert isinstance(token.tokens[0], CounterToken) + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_temp_not_monotonic_timeout_token_plus_bigger_not_monotonic_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(left_addictional_kwargs, right_addictional_kwargs): + right_timeout_token = TimeoutToken(2, ConditionToken(lambda: True), **right_addictional_kwargs) + token = TimeoutToken(1, CounterToken(5), **left_addictional_kwargs) + right_timeout_token + + TimeoutToken(1, CounterToken(5), TimeoutToken(2, ConditionToken(lambda: True))) + + assert isinstance(token, TimeoutToken) + assert isinstance(token.tokens[0], CounterToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + assert token.timeout == 1 + assert token.tokens[1].timeout == 2 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert token.tokens[1] is right_timeout_token + assert token is not right_timeout_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_timeout_token_plus_less_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(addictional_kwargs): + left = TimeoutToken(2, CounterToken(5), **addictional_kwargs) + right = TimeoutToken(1, ConditionToken(lambda: False), **addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert isinstance(token.tokens[0].tokens[0], CounterToken) + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert len(token.tokens[0].tokens[0].tokens) == 0 + assert token.tokens[0] is left + assert token.tokens[1] is right + assert token.tokens[0].timeout == 2 + assert token.tokens[1].timeout == 1 + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_timeout_token_plus_less_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(left_addictional_kwargs, right_addictional_kwargs): + left = TimeoutToken(2, CounterToken(5), **left_addictional_kwargs) + right = TimeoutToken(1, ConditionToken(lambda: False), **right_addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert isinstance(token.tokens[0].tokens[0], CounterToken) + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert len(token.tokens[0].tokens[0].tokens) == 0 + assert token.tokens[0] is left + assert token.tokens[1] is right + assert token.tokens[0].timeout == 2 + assert token.tokens[1].timeout == 1 + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_or_equal_not_monotonic_timeout_token_plus_bigger_or_equal_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(timeout_for_equal_or_bigger_token, addictional_kwargs): + left = TimeoutToken(1, CounterToken(5), **addictional_kwargs) + right = TimeoutToken(timeout_for_equal_or_bigger_token, ConditionToken(lambda: False), **addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert isinstance(token.tokens[0].tokens[0], CounterToken) + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert len(token.tokens[0].tokens[0].tokens) == 0 + assert token.tokens[0] is left + assert token.tokens[1] is right + assert token.tokens[0].timeout == 1 + assert token.tokens[1].timeout == timeout_for_equal_or_bigger_token + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_or_equal_not_monotonic_timeout_token_plus_bigger_or_equal_not_monotonic_timeout_token_with_not_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(timeout_for_equal_or_bigger_token, left_addictional_kwargs, right_addictional_kwargs): + left = TimeoutToken(1, CounterToken(5), **left_addictional_kwargs) + right = TimeoutToken(timeout_for_equal_or_bigger_token, ConditionToken(lambda: False), **right_addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert isinstance(token.tokens[0].tokens[0], CounterToken) + assert isinstance(token.tokens[1].tokens[0], ConditionToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[1].tokens) == 1 + assert len(token.tokens[1].tokens[0].tokens) == 0 + assert len(token.tokens[0].tokens[0].tokens) == 0 + assert token.tokens[0] is left + assert token.tokens[1] is right + assert token.tokens[0].timeout == 1 + assert token.tokens[1].timeout == timeout_for_equal_or_bigger_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_same_monotonic_flag_with_temp_counter_token_at_left(addictional_kwargs): + token = TimeoutToken(2, CounterToken(5), **addictional_kwargs) + TimeoutToken(1, **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], CounterToken) + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_not_same_monotonic_flag_with_temp_counter_token_at_left(left_addictional_kwargs, right_addictional_kwargs): + token = TimeoutToken(2, CounterToken(5), **left_addictional_kwargs) + TimeoutToken(1, **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 2 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert isinstance(token.tokens[0], CounterToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[1].timeout == 1 + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_temp_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_counter_token_at_left(timeout_for_equal_or_bigger_token, addictional_kwargs): + token = TimeoutToken(1, CounterToken(5), **addictional_kwargs) + TimeoutToken(timeout_for_equal_or_bigger_token, **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert isinstance(token.tokens[0], CounterToken) + assert token.timeout == 1 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert isinstance(token.tokens[0], CounterToken) + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_temp_not_monotonic_timeout_token_with_not_same_monotonic_flag_with_temp_counter_token_at_left(timeout_for_equal_or_bigger_token, left_addictional_kwargs, right_addictional_kwargs): + token = TimeoutToken(1, CounterToken(5), **left_addictional_kwargs) + TimeoutToken(timeout_for_equal_or_bigger_token, **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert token.tokens[1].timeout == timeout_for_equal_or_bigger_token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert isinstance(token.tokens[0], CounterToken) + assert isinstance(token.tokens[1], TimeoutToken) + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_timeout_token_plus_less_temp_timeout_token_with_same_monotonic_flag_with_temp_counter_token_at_left(addictional_kwargs): + left_timeout_token = TimeoutToken(2, CounterToken(5), **addictional_kwargs) + token = left_timeout_token + TimeoutToken(1, **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[0].tokens[0], CounterToken) + assert token is not left_timeout_token + assert token.tokens[0] is left_timeout_token + assert token.timeout == 1 + assert token.tokens[0].timeout == 2 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[0].tokens[0].tokens) == 0 + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_timeout_token_plus_less_temp_timeout_token_with_not_same_monotonic_flag_with_temp_counter_token_at_left(left_addictional_kwargs, right_addictional_kwargs): + left_timeout_token = TimeoutToken(2, CounterToken(5), **left_addictional_kwargs) + token = left_timeout_token + TimeoutToken(1, **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[0].tokens[0], CounterToken) + assert token is not left_timeout_token + assert token.tokens[0] is left_timeout_token + assert token.timeout == 1 + assert token.tokens[0].timeout == 2 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[0].tokens[0].tokens) == 0 + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_not_monotonic_timeout_token_plus_bigger_temp_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_counter_token_at_left(addictional_kwargs): + left_timeout_token = TimeoutToken(1, CounterToken(5), **addictional_kwargs) + token = left_timeout_token + TimeoutToken(2, **addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert isinstance(token.tokens[0], CounterToken) + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 0 + assert token is left_timeout_token + assert token.timeout == 1 + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_not_monotonic_timeout_token_plus_bigger_temp_not_monotonic_timeout_token_with_not_same_monotonic_flag_with_temp_counter_token_at_left(left_addictional_kwargs, right_addictional_kwargs): + left_timeout_token = TimeoutToken(1, CounterToken(5), **left_addictional_kwargs) + token = left_timeout_token + TimeoutToken(2, **right_addictional_kwargs) + + assert isinstance(token, TimeoutToken) + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[0].tokens[0], CounterToken) + assert token.timeout == 2 + assert token.tokens[0].timeout == 1 + assert token.tokens[0] is left_timeout_token + assert token is not left_timeout_token + assert token.timeout == 2 + assert len(token.tokens) == 1 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[0].tokens[0].tokens) == 0 + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_temp_timeout_token_plus_less_timeout_token_with_same_monotonic_flag_with_temp_counter_token_at_left(addictional_kwargs): + right_timeout_token = TimeoutToken(1, **addictional_kwargs) + token = TimeoutToken(2, CounterToken(5), **addictional_kwargs) + right_timeout_token + + assert isinstance(token, SimpleToken) + assert isinstance(token.tokens[0], CounterToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[1].timeout == 1 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert token.tokens[1] is right_timeout_token + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_temp_timeout_token_plus_less_timeout_token_with_not_same_monotonic_flag_with_temp_counter_token_at_left(left_addictional_kwargs, right_addictional_kwargs): + right_timeout_token = TimeoutToken(1, **right_addictional_kwargs) + token = TimeoutToken(2, CounterToken(5), **left_addictional_kwargs) + right_timeout_token + + assert isinstance(token, TimeoutToken) + assert isinstance(token.tokens[0], CounterToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.tokens[1].timeout == 1 + assert token.timeout == 2 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert token.tokens[1] is right_timeout_token + assert token is not right_timeout_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_temp_not_monotonic_timeout_token_plus_bigger_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_counter_token_at_left(addictional_kwargs): + right_timeout_token = TimeoutToken(2, **addictional_kwargs) + token = TimeoutToken(1, CounterToken(5), **addictional_kwargs) + right_timeout_token + + assert isinstance(token, TimeoutToken) + assert token.timeout == 1 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert token.tokens[1].timeout == 2 + assert token.tokens[1] is right_timeout_token + assert isinstance(token.tokens[0], CounterToken) + assert isinstance(token.tokens[1], TimeoutToken) + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_temp_not_monotonic_timeout_token_plus_bigger_not_monotonic_timeout_token_with_not_same_monotonic_flag_with_temp_counter_token_at_left(left_addictional_kwargs, right_addictional_kwargs): + right_timeout_token = TimeoutToken(2, **right_addictional_kwargs) + token = TimeoutToken(1, CounterToken(5), **left_addictional_kwargs) + right_timeout_token + + assert isinstance(token, TimeoutToken) + assert isinstance(token.tokens[0], CounterToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert token.timeout == 1 + assert token.tokens[1].timeout == 2 + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 0 + assert len(token.tokens[1].tokens) == 0 + assert token.tokens[1] is right_timeout_token + assert token is not right_timeout_token + + +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_bigger_timeout_token_plus_less_timeout_token_with_same_monotonic_flag_with_temp_counter_token_at_left(addictional_kwargs): + left = TimeoutToken(2, CounterToken(5), **addictional_kwargs) + right = TimeoutToken(1, **addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert isinstance(token.tokens[0].tokens[0], CounterToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[1].tokens) == 0 + assert len(token.tokens[0].tokens[0].tokens) == 0 + assert token.tokens[0] is left + assert token.tokens[1] is right + assert token.tokens[0].timeout == 2 + assert token.tokens[1].timeout == 1 + + +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_bigger_timeout_token_plus_less_timeout_token_with_not_same_monotonic_flag_with_temp_counter_token_at_left(left_addictional_kwargs, right_addictional_kwargs): + left = TimeoutToken(2, CounterToken(5), **left_addictional_kwargs) + right = TimeoutToken(1, **right_addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert isinstance(token.tokens[0].tokens[0], CounterToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[1].tokens) == 0 + assert len(token.tokens[0].tokens[0].tokens) == 0 + assert token.tokens[0] is left + assert token.tokens[1] is right + assert token.tokens[0].timeout == 2 + assert token.tokens[1].timeout == 1 + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['addictional_kwargs'], + [ + ({'monotonic': False},), + ({},), + ({'monotonic': True},), + ], +) +def test_less_or_equal_not_monotonic_timeout_token_plus_bigger_or_equal_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_counter_token_at_left(timeout_for_equal_or_bigger_token, addictional_kwargs): + left = TimeoutToken(1, CounterToken(5), **addictional_kwargs) + right = TimeoutToken(timeout_for_equal_or_bigger_token, **addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert isinstance(token.tokens[0].tokens[0], CounterToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[1].tokens) == 0 + assert len(token.tokens[0].tokens[0].tokens) == 0 + assert token.tokens[0] is left + assert token.tokens[1] is right + assert token.tokens[0].timeout == 1 + assert token.tokens[1].timeout == timeout_for_equal_or_bigger_token + + +@pytest.mark.parametrize( + ['timeout_for_equal_or_bigger_token'], + [ + (1,), + (2,), + ], +) +@pytest.mark.parametrize( + ['left_addictional_kwargs', 'right_addictional_kwargs'], + [ + ({'monotonic': False}, {'monotonic': True}), + ({}, {'monotonic': True}), + ({'monotonic': True}, {'monotonic': False}), + ({'monotonic': True}, {}), + ], +) +def test_less_or_equal_not_monotonic_timeout_token_plus_bigger_or_equal_not_monotonic_timeout_token_with_not_same_monotonic_flag_with_temp_counter_token_at_left(timeout_for_equal_or_bigger_token, left_addictional_kwargs, right_addictional_kwargs): + left = TimeoutToken(1, CounterToken(5), **left_addictional_kwargs) + right = TimeoutToken(timeout_for_equal_or_bigger_token, **right_addictional_kwargs) + token = left + right + + assert isinstance(token, SimpleToken) + assert isinstance(token.tokens[0], TimeoutToken) + assert isinstance(token.tokens[1], TimeoutToken) + assert isinstance(token.tokens[0].tokens[0], CounterToken) + assert token + assert len(token.tokens) == 2 + assert len(token.tokens[0].tokens) == 1 + assert len(token.tokens[1].tokens) == 0 + assert len(token.tokens[0].tokens[0].tokens) == 0 + assert token.tokens[0] is left + assert token.tokens[1] is right + assert token.tokens[0].timeout == 1 + assert token.tokens[1].timeout == timeout_for_equal_or_bigger_token From ab318ae756c6c012f84c10078394132d27af77a3 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Fri, 9 Aug 2024 01:02:57 +0300 Subject: [PATCH 37/44] check cancel status of tokens before all when doing sum --- cantok/tokens/abstract/abstract_token.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index 453f807..0d6e413 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -55,6 +55,9 @@ def __add__(self, item: 'AbstractToken') -> 'AbstractToken': from cantok import SimpleToken, DefaultToken, TimeoutToken + if self._cancelled or item._cancelled: + return SimpleToken(cancelled=True) + nested_tokens = [] container_token: Optional[AbstractToken] = None @@ -79,9 +82,7 @@ def __add__(self, item: 'AbstractToken') -> 'AbstractToken': return self for token in self, item: - if token._cancelled: - return SimpleToken(cancelled=True) - elif isinstance(token, SimpleToken) and getrefcount(token) < 6: + if isinstance(token, SimpleToken) and getrefcount(token) < 6: nested_tokens.extend(token.tokens) elif isinstance(token, DefaultToken): pass From 92d4f625024471a07cd30eb057f0ba648400226a Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Fri, 9 Aug 2024 01:06:59 +0300 Subject: [PATCH 38/44] new tests --- tests/units/tokens/test_timeout_token.py | 72 ++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index bc378b2..85bbc5e 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -1963,3 +1963,75 @@ def test_less_or_equal_not_monotonic_timeout_token_plus_bigger_or_equal_not_mono assert token.tokens[1] is right assert token.tokens[0].timeout == 1 assert token.tokens[1].timeout == timeout_for_equal_or_bigger_token + + +def test_temp_negative_timeout_token_plus_temp_timeout_token(): + token = TimeoutToken(1, cancelled=True) + TimeoutToken(1) + + assert isinstance(token, SimpleToken) + assert not token + assert not token.tokens + + +def test_temp_timeout_token_plus_temp_negative_timeout_token(): + token = TimeoutToken(1) + TimeoutToken(1, cancelled=True) + + assert isinstance(token, SimpleToken) + assert not token + assert not token.tokens + + +def test_not_temp_negative_timeout_token_plus_temp_timeout_token(): + first = TimeoutToken(1, cancelled=True) + token = first + TimeoutToken(1) + + assert isinstance(token, SimpleToken) + assert not token + assert not token.tokens + + +def test_not_temp_timeout_token_plus_temp_negative_timeout_token(): + first = TimeoutToken(1) + token = first + TimeoutToken(1, cancelled=True) + + assert isinstance(token, SimpleToken) + assert not token + assert not token.tokens + + +def test_not_temp_negative_timeout_token_plus_timeout_token(): + first = TimeoutToken(1, cancelled=True) + second = TimeoutToken(1) + token = first + second + + assert isinstance(token, SimpleToken) + assert not token + assert not token.tokens + + +def test_not_temp_timeout_token_plus_negative_timeout_token(): + first = TimeoutToken(1) + second = TimeoutToken(1, cancelled=True) + token = first + second + + assert isinstance(token, SimpleToken) + assert not token + assert not token.tokens + + +def test_temp_negative_timeout_token_plus_temp_timeout_token(): + second = TimeoutToken(1) + token = TimeoutToken(1, cancelled=True) + second + + assert isinstance(token, SimpleToken) + assert not token + assert not token.tokens + + +def test_temp_timeout_token_plus_temp_negative_timeout_token(): + second = TimeoutToken(1, cancelled=True) + token = TimeoutToken(1) + second + + assert isinstance(token, SimpleToken) + assert not token + assert not token.tokens From 203ce993568c797bdf4c3aab18628eb352531175 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Fri, 9 Aug 2024 01:08:23 +0300 Subject: [PATCH 39/44] no extra imports --- cantok/tokens/timeout_token.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cantok/tokens/timeout_token.py b/cantok/tokens/timeout_token.py index 1bbe4a4..d9dff14 100644 --- a/cantok/tokens/timeout_token.py +++ b/cantok/tokens/timeout_token.py @@ -1,11 +1,9 @@ from time import monotonic_ns, perf_counter -from sys import getrefcount -from typing import Union, Callable, List, Dict, Any +from typing import Union, Callable, Dict, Any from cantok import AbstractToken from cantok import ConditionToken from cantok.errors import TimeoutCancellationError -from cantok.types import IterableWithTokens class TimeoutToken(ConditionToken): From d9276b3d67d8973f3d14b1a83d5db67c3c4ca2e0 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Fri, 9 Aug 2024 01:10:41 +0300 Subject: [PATCH 40/44] rename some tests --- tests/units/tokens/test_timeout_token.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index 85bbc5e..83512ff 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -2019,7 +2019,7 @@ def test_not_temp_timeout_token_plus_negative_timeout_token(): assert not token.tokens -def test_temp_negative_timeout_token_plus_temp_timeout_token(): +def test_temp_negative_timeout_token_plus_timeout_token(): second = TimeoutToken(1) token = TimeoutToken(1, cancelled=True) + second @@ -2028,7 +2028,7 @@ def test_temp_negative_timeout_token_plus_temp_timeout_token(): assert not token.tokens -def test_temp_timeout_token_plus_temp_negative_timeout_token(): +def test_temp_timeout_token_plus_negative_timeout_token(): second = TimeoutToken(1, cancelled=True) token = TimeoutToken(1) + second From a420ab5556033d14e14c9962dee0dfed9773d488 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Fri, 9 Aug 2024 01:14:57 +0300 Subject: [PATCH 41/44] print in a test --- tests/units/tokens/test_timeout_token.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index 83512ff..b3f7790 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -1166,6 +1166,8 @@ def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_not_same_mo def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_temp_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(timeout_for_equal_or_bigger_token, addictional_kwargs): token = TimeoutToken(1, CounterToken(5), **addictional_kwargs) + TimeoutToken(timeout_for_equal_or_bigger_token, ConditionToken(lambda: True), **addictional_kwargs) + print(repr(token)) + assert isinstance(token, TimeoutToken) assert token.timeout == 1 assert len(token.tokens) == 2 From 26d596c9c6ff59986555fafd6e45844c537cd960 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Fri, 9 Aug 2024 01:21:37 +0300 Subject: [PATCH 42/44] new checks in a test --- tests/units/tokens/test_timeout_token.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/units/tokens/test_timeout_token.py b/tests/units/tokens/test_timeout_token.py index b3f7790..88a1906 100644 --- a/tests/units/tokens/test_timeout_token.py +++ b/tests/units/tokens/test_timeout_token.py @@ -1166,15 +1166,12 @@ def test_bigger_temp_timeout_token_plus_less_temp_timeout_token_with_not_same_mo def test_less_or_equal_temp_not_monotonic_timeout_token_plus_bigger_or_equal_temp_not_monotonic_timeout_token_with_same_monotonic_flag_with_temp_condition_token_at_right_and_counter_token_at_left(timeout_for_equal_or_bigger_token, addictional_kwargs): token = TimeoutToken(1, CounterToken(5), **addictional_kwargs) + TimeoutToken(timeout_for_equal_or_bigger_token, ConditionToken(lambda: True), **addictional_kwargs) - print(repr(token)) - assert isinstance(token, TimeoutToken) assert token.timeout == 1 assert len(token.tokens) == 2 assert len(token.tokens[0].tokens) == 0 assert len(token.tokens[1].tokens) == 0 - assert isinstance(token.tokens[0], CounterToken) - assert isinstance(token.tokens[1], ConditionToken) + assert {type(token.tokens[0]), type(token.tokens[1])} == {CounterToken, ConditionToken} @pytest.mark.parametrize( From 92ce7c37d0768b6f55a928bab396bea657648986 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Fri, 9 Aug 2024 01:26:47 +0300 Subject: [PATCH 43/44] no extra parameters --- cantok/tokens/abstract/abstract_token.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cantok/tokens/abstract/abstract_token.py b/cantok/tokens/abstract/abstract_token.py index 0d6e413..625fce0 100644 --- a/cantok/tokens/abstract/abstract_token.py +++ b/cantok/tokens/abstract/abstract_token.py @@ -94,13 +94,13 @@ def __add__(self, item: 'AbstractToken') -> 'AbstractToken': if container_token is None: return SimpleToken(*nested_tokens) else: - container_token.tokens.extend(container_token.filter_tokens(nested_tokens, expected_refcount=6)) + container_token.tokens.extend(container_token.filter_tokens(nested_tokens)) return container_token def __bool__(self) -> bool: return self.keep_on() - def filter_tokens(self, tokens: IterableWithTokens, expected_refcount: int = 0) -> List['AbstractToken']: # type: ignore[type-arg] + def filter_tokens(self, tokens: IterableWithTokens) -> List['AbstractToken']: # type: ignore[type-arg] from cantok import DefaultToken result: List[AbstractToken] = [] From 0e236f3104f16f6e01079b74c620fd0a811ca535 Mon Sep 17 00:00:00 2001 From: Evgeniy Blinov Date: Fri, 9 Aug 2024 01:27:11 +0300 Subject: [PATCH 44/44] new version tag --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 75cc91b..6d39b25 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "cantok" -version = "0.0.28" +version = "0.0.29" authors = [ { name="Evgeniy Blinov", email="zheni-b@yandex.ru" }, ]