From a635376e146c42340f3ba400e3224bed38c7bf7f Mon Sep 17 00:00:00 2001 From: Oleg Ovcharuk Date: Thu, 5 Feb 2026 16:08:00 +0300 Subject: [PATCH 1/5] Fix possible race condition in topic common --- test-requirements.txt | 2 +- ydb/_topic_common/common.py | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/test-requirements.txt b/test-requirements.txt index 2711066d..cb6fe7e2 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -38,7 +38,7 @@ zipp==3.19.1 aiohttp>=3.9.0 pytest-pep8 pytest-flake8 -flake8==3.9.2 +flake8>=5.0.0 sqlalchemy==1.4.26 pylint-protobuf cython diff --git a/ydb/_topic_common/common.py b/ydb/_topic_common/common.py index 68ddcf8d..420b55ec 100644 --- a/ydb/_topic_common/common.py +++ b/ydb/_topic_common/common.py @@ -36,8 +36,6 @@ def wrapper(rpc_state, response_pb, driver=None): def _get_shared_event_loop() -> asyncio.AbstractEventLoop: - global _shared_event_loop - if _shared_event_loop is not None: return _shared_event_loop @@ -45,12 +43,17 @@ def _get_shared_event_loop() -> asyncio.AbstractEventLoop: if _shared_event_loop is not None: return _shared_event_loop - event_loop_set_done: concurrent.futures.Future[asyncio.AbstractEventLoop] = concurrent.futures.Future() + loop_ready: threading.Event = threading.Event() def start_event_loop(): event_loop = asyncio.new_event_loop() - event_loop_set_done.set_result(event_loop) asyncio.set_event_loop(event_loop) + + global _shared_event_loop + _shared_event_loop = event_loop + + # Signal that loop is running and ready to accept tasks + event_loop.call_soon(loop_ready.set) event_loop.run_forever() t = threading.Thread( @@ -60,7 +63,8 @@ def start_event_loop(): ) t.start() - _shared_event_loop = event_loop_set_done.result() + loop_ready.wait() + assert _shared_event_loop is not None return _shared_event_loop From ed47dee3d387bd1341ff869dde1c3e8125cfd8f5 Mon Sep 17 00:00:00 2001 From: Oleg Ovcharuk Date: Thu, 5 Feb 2026 16:31:16 +0300 Subject: [PATCH 2/5] fix linter errors --- examples/basic_example_v1/basic_example.py | 2 -- examples/coordination/example.py | 2 +- examples/topic/writer_example.py | 2 +- tests/iam/test_auth.py | 2 +- tests/scheme/scheme_test.py | 2 +- tests/test_errors.py | 2 +- tests/topics/test_topic_reader.py | 2 -- tests/topics/test_topic_writer.py | 2 +- ydb/_topic_common/common.py | 5 ++++- ydb/_topic_common/common_test.py | 2 +- ydb/aio/connection.py | 1 - ydb/connection.py | 1 - ydb/retries.py | 4 ++-- ydb/table_test.py | 4 ++-- 14 files changed, 15 insertions(+), 18 deletions(-) diff --git a/examples/basic_example_v1/basic_example.py b/examples/basic_example_v1/basic_example.py index 09a77a67..7a715208 100644 --- a/examples/basic_example_v1/basic_example.py +++ b/examples/basic_example_v1/basic_example.py @@ -64,8 +64,6 @@ def fill_tables_with_data(pool, path): - global FillDataQuery - def callee(session): prepared_query = session.prepare(FillDataQuery.format(path)) session.transaction(ydb.SerializableReadWrite()).execute( diff --git a/examples/coordination/example.py b/examples/coordination/example.py index 0b817ff3..42f89fe6 100644 --- a/examples/coordination/example.py +++ b/examples/coordination/example.py @@ -43,7 +43,7 @@ def run(endpoint, database): threads = [] for i in range(4): - worker_name = f"worker {i+1}" + worker_name = f"worker {i + 1}" if i < 2: thread = threading.Thread(target=linear_workload, args=(driver.coordination_client, worker_name)) else: diff --git a/examples/topic/writer_example.py b/examples/topic/writer_example.py index b122e78c..99346a27 100644 --- a/examples/topic/writer_example.py +++ b/examples/topic/writer_example.py @@ -1,7 +1,7 @@ import concurrent.futures import datetime from typing import Dict, List -from concurrent.futures import Future, wait +from concurrent.futures import Future, wait # noqa: F401 import ydb from ydb import TopicWriterMessage diff --git a/tests/iam/test_auth.py b/tests/iam/test_auth.py index 54117b53..09a1c03a 100644 --- a/tests/iam/test_auth.py +++ b/tests/iam/test_auth.py @@ -14,7 +14,7 @@ def __init__(self, account_id, key_id, private_key, iam_endpoint=None, iam_chann self.iam_channel_credentials = iam_channel_credentials def __eq__(self, other): - return self.__dict__ == other.__dict__ if type(self) == type(other) else False + return self.__dict__ == other.__dict__ if type(self) is type(other) else False @patch("builtins.open", new_callable=mock_open, read_data=CONTENT1) diff --git a/tests/scheme/scheme_test.py b/tests/scheme/scheme_test.py index 4f93c8ea..1a105620 100644 --- a/tests/scheme/scheme_test.py +++ b/tests/scheme/scheme_test.py @@ -1,4 +1,4 @@ -import typing +import typing # noqa: F401 import pytest import ydb diff --git a/tests/test_errors.py b/tests/test_errors.py index 93f6f4a3..bdecebef 100644 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -11,7 +11,7 @@ def test_scheme_error(driver_sync, database): server_code = ydb.issues.StatusCode.SCHEME_ERROR - assert type(exc.value) == ydb.issues.SchemeError + assert type(exc.value) is ydb.issues.SchemeError assert exc.value.status == server_code assert f"server_code: {server_code}" in str(exc.value) assert "Path does not exist" in str(exc.value) diff --git a/tests/topics/test_topic_reader.py b/tests/topics/test_topic_reader.py index 2227a739..6bb3ae09 100644 --- a/tests/topics/test_topic_reader.py +++ b/tests/topics/test_topic_reader.py @@ -494,7 +494,6 @@ async def test_offsets_updated_after_reconnect(self, driver, topic_selector): class CustomEventHandler(ydb.TopicReaderEvents.EventHandler): def on_partition_get_start_offset(self, event): - nonlocal current_offset return ydb.TopicReaderEvents.OnPartitionGetStartOffsetResponse(current_offset) reader = driver.topic_client.reader( @@ -616,7 +615,6 @@ def test_offsets_updated_after_reconnect(self, driver_sync, topic_selector): class CustomEventHandler(ydb.TopicReaderEvents.EventHandler): def on_partition_get_start_offset(self, event): - nonlocal current_offset return ydb.TopicReaderEvents.OnPartitionGetStartOffsetResponse(current_offset) reader = driver_sync.topic_client.reader( diff --git a/tests/topics/test_topic_writer.py b/tests/topics/test_topic_writer.py index aed552ab..df729e96 100644 --- a/tests/topics/test_topic_writer.py +++ b/tests/topics/test_topic_writer.py @@ -1,7 +1,7 @@ from __future__ import annotations import asyncio -from typing import List +from typing import List # noqa: F401 import pytest diff --git a/ydb/_topic_common/common.py b/ydb/_topic_common/common.py index 420b55ec..74989e6f 100644 --- a/ydb/_topic_common/common.py +++ b/ydb/_topic_common/common.py @@ -64,7 +64,10 @@ def start_event_loop(): t.start() loop_ready.wait() - assert _shared_event_loop is not None + + if _shared_event_loop is None: + raise RuntimeError("Event loop was not properly initialized") + return _shared_event_loop diff --git a/ydb/_topic_common/common_test.py b/ydb/_topic_common/common_test.py index b31f9af9..ee8e29b9 100644 --- a/ydb/_topic_common/common_test.py +++ b/ydb/_topic_common/common_test.py @@ -248,7 +248,7 @@ def test_safe_callback_with_0_timeout_timeout(self, separate_loop, caller): async def callback(): try: - nonlocal callback_loop, cancelled + nonlocal callback_loop, cancelled # noqa: F824 callback_loop = asyncio.get_running_loop() await asyncio.sleep(1) diff --git a/ydb/aio/connection.py b/ydb/aio/connection.py index 9a031ff1..c4711f75 100644 --- a/ydb/aio/connection.py +++ b/ydb/aio/connection.py @@ -157,7 +157,6 @@ def __init__( driver_config: Optional[DriverConfig] = None, endpoint_options: Optional[EndpointOptions] = None, ) -> None: - global _stubs_list self.endpoint = endpoint self.endpoint_key = EndpointKey(self.endpoint, getattr(endpoint_options, "node_id", None)) self.node_id = getattr(endpoint_options, "node_id", None) diff --git a/ydb/connection.py b/ydb/connection.py index fc05544b..6ac700b8 100644 --- a/ydb/connection.py +++ b/ydb/connection.py @@ -416,7 +416,6 @@ def __init__( discovered by the YDB endpoint discovery mechanism :param driver_config: A driver config instance to be used for RPC call interception """ - global _stubs_list self.endpoint = endpoint self.node_id = getattr(endpoint_options, "node_id", None) self.endpoint_key = EndpointKey(endpoint, getattr(endpoint_options, "node_id", None)) diff --git a/ydb/retries.py b/ydb/retries.py index 0b3bec52..c151e3d2 100644 --- a/ydb/retries.py +++ b/ydb/retries.py @@ -77,7 +77,7 @@ def __init__(self, timeout: float) -> None: def __eq__(self, other: object) -> bool: return ( - type(self) == type(other) and isinstance(other, YdbRetryOperationSleepOpt) and self.timeout == other.timeout + type(self) is type(other) and isinstance(other, YdbRetryOperationSleepOpt) and self.timeout == other.timeout ) def __repr__(self) -> str: @@ -91,7 +91,7 @@ def __init__(self, result: Any) -> None: def __eq__(self, other: object) -> bool: return ( - type(self) == type(other) + type(self) is type(other) and isinstance(other, YdbRetryOperationFinalResult) and self.result == other.result and self.exc == other.exc diff --git a/ydb/table_test.py b/ydb/table_test.py index d5d86e05..b365fda1 100644 --- a/ydb/table_test.py +++ b/ydb/table_test.py @@ -14,7 +14,7 @@ def test_retry_operation_impl(monkeypatch): monkeypatch.setattr( issues.Error, "__eq__", - lambda self, other: type(self) == type(other) and self.message == other.message, + lambda self, other: type(self) is type(other) and self.message == other.message, ) retry_once_settings = RetrySettings( @@ -43,7 +43,7 @@ def __init__(self, message): self.message = message def __eq__(self, other): - return type(self) == type(other) and self.message == other.message + return type(self) is type(other) and self.message == other.message def check_unretriable_error(err_type, call_ydb_handler): retry_once_settings.on_ydb_error_callback.reset_mock() From 9bd9fab4077c176e169b5baeb5d79bbf135ab497 Mon Sep 17 00:00:00 2001 From: Oleg Ovcharuk Date: Thu, 5 Feb 2026 16:36:31 +0300 Subject: [PATCH 3/5] fix logic --- ydb/_topic_common/common.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ydb/_topic_common/common.py b/ydb/_topic_common/common.py index 74989e6f..678f5ff6 100644 --- a/ydb/_topic_common/common.py +++ b/ydb/_topic_common/common.py @@ -49,11 +49,13 @@ def start_event_loop(): event_loop = asyncio.new_event_loop() asyncio.set_event_loop(event_loop) - global _shared_event_loop - _shared_event_loop = event_loop + def on_loop_started(): + # Set global only when loop is actually running + global _shared_event_loop + _shared_event_loop = event_loop + loop_ready.set() - # Signal that loop is running and ready to accept tasks - event_loop.call_soon(loop_ready.set) + event_loop.call_soon(on_loop_started) event_loop.run_forever() t = threading.Thread( From bd30db0131770d354d7d6baa5888736f5a4bb163 Mon Sep 17 00:00:00 2001 From: Oleg Ovcharuk Date: Thu, 5 Feb 2026 16:44:56 +0300 Subject: [PATCH 4/5] Revert "fix linter errors" This reverts commit ed47dee3d387bd1341ff869dde1c3e8125cfd8f5. --- examples/basic_example_v1/basic_example.py | 2 ++ examples/coordination/example.py | 2 +- examples/topic/writer_example.py | 2 +- test-requirements.txt | 2 +- tests/iam/test_auth.py | 2 +- tests/scheme/scheme_test.py | 2 +- tests/test_errors.py | 2 +- tests/topics/test_topic_reader.py | 2 ++ tests/topics/test_topic_writer.py | 2 +- ydb/_topic_common/common_test.py | 2 +- ydb/aio/connection.py | 1 + ydb/connection.py | 1 + ydb/retries.py | 4 ++-- ydb/table_test.py | 4 ++-- 14 files changed, 18 insertions(+), 12 deletions(-) diff --git a/examples/basic_example_v1/basic_example.py b/examples/basic_example_v1/basic_example.py index 7a715208..09a77a67 100644 --- a/examples/basic_example_v1/basic_example.py +++ b/examples/basic_example_v1/basic_example.py @@ -64,6 +64,8 @@ def fill_tables_with_data(pool, path): + global FillDataQuery + def callee(session): prepared_query = session.prepare(FillDataQuery.format(path)) session.transaction(ydb.SerializableReadWrite()).execute( diff --git a/examples/coordination/example.py b/examples/coordination/example.py index 42f89fe6..0b817ff3 100644 --- a/examples/coordination/example.py +++ b/examples/coordination/example.py @@ -43,7 +43,7 @@ def run(endpoint, database): threads = [] for i in range(4): - worker_name = f"worker {i + 1}" + worker_name = f"worker {i+1}" if i < 2: thread = threading.Thread(target=linear_workload, args=(driver.coordination_client, worker_name)) else: diff --git a/examples/topic/writer_example.py b/examples/topic/writer_example.py index 99346a27..b122e78c 100644 --- a/examples/topic/writer_example.py +++ b/examples/topic/writer_example.py @@ -1,7 +1,7 @@ import concurrent.futures import datetime from typing import Dict, List -from concurrent.futures import Future, wait # noqa: F401 +from concurrent.futures import Future, wait import ydb from ydb import TopicWriterMessage diff --git a/test-requirements.txt b/test-requirements.txt index cb6fe7e2..a5b65963 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -38,7 +38,7 @@ zipp==3.19.1 aiohttp>=3.9.0 pytest-pep8 pytest-flake8 -flake8>=5.0.0 +flake8==6.1.0 sqlalchemy==1.4.26 pylint-protobuf cython diff --git a/tests/iam/test_auth.py b/tests/iam/test_auth.py index 09a1c03a..54117b53 100644 --- a/tests/iam/test_auth.py +++ b/tests/iam/test_auth.py @@ -14,7 +14,7 @@ def __init__(self, account_id, key_id, private_key, iam_endpoint=None, iam_chann self.iam_channel_credentials = iam_channel_credentials def __eq__(self, other): - return self.__dict__ == other.__dict__ if type(self) is type(other) else False + return self.__dict__ == other.__dict__ if type(self) == type(other) else False @patch("builtins.open", new_callable=mock_open, read_data=CONTENT1) diff --git a/tests/scheme/scheme_test.py b/tests/scheme/scheme_test.py index 1a105620..4f93c8ea 100644 --- a/tests/scheme/scheme_test.py +++ b/tests/scheme/scheme_test.py @@ -1,4 +1,4 @@ -import typing # noqa: F401 +import typing import pytest import ydb diff --git a/tests/test_errors.py b/tests/test_errors.py index bdecebef..93f6f4a3 100644 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -11,7 +11,7 @@ def test_scheme_error(driver_sync, database): server_code = ydb.issues.StatusCode.SCHEME_ERROR - assert type(exc.value) is ydb.issues.SchemeError + assert type(exc.value) == ydb.issues.SchemeError assert exc.value.status == server_code assert f"server_code: {server_code}" in str(exc.value) assert "Path does not exist" in str(exc.value) diff --git a/tests/topics/test_topic_reader.py b/tests/topics/test_topic_reader.py index 6bb3ae09..2227a739 100644 --- a/tests/topics/test_topic_reader.py +++ b/tests/topics/test_topic_reader.py @@ -494,6 +494,7 @@ async def test_offsets_updated_after_reconnect(self, driver, topic_selector): class CustomEventHandler(ydb.TopicReaderEvents.EventHandler): def on_partition_get_start_offset(self, event): + nonlocal current_offset return ydb.TopicReaderEvents.OnPartitionGetStartOffsetResponse(current_offset) reader = driver.topic_client.reader( @@ -615,6 +616,7 @@ def test_offsets_updated_after_reconnect(self, driver_sync, topic_selector): class CustomEventHandler(ydb.TopicReaderEvents.EventHandler): def on_partition_get_start_offset(self, event): + nonlocal current_offset return ydb.TopicReaderEvents.OnPartitionGetStartOffsetResponse(current_offset) reader = driver_sync.topic_client.reader( diff --git a/tests/topics/test_topic_writer.py b/tests/topics/test_topic_writer.py index df729e96..aed552ab 100644 --- a/tests/topics/test_topic_writer.py +++ b/tests/topics/test_topic_writer.py @@ -1,7 +1,7 @@ from __future__ import annotations import asyncio -from typing import List # noqa: F401 +from typing import List import pytest diff --git a/ydb/_topic_common/common_test.py b/ydb/_topic_common/common_test.py index ee8e29b9..b31f9af9 100644 --- a/ydb/_topic_common/common_test.py +++ b/ydb/_topic_common/common_test.py @@ -248,7 +248,7 @@ def test_safe_callback_with_0_timeout_timeout(self, separate_loop, caller): async def callback(): try: - nonlocal callback_loop, cancelled # noqa: F824 + nonlocal callback_loop, cancelled callback_loop = asyncio.get_running_loop() await asyncio.sleep(1) diff --git a/ydb/aio/connection.py b/ydb/aio/connection.py index c4711f75..9a031ff1 100644 --- a/ydb/aio/connection.py +++ b/ydb/aio/connection.py @@ -157,6 +157,7 @@ def __init__( driver_config: Optional[DriverConfig] = None, endpoint_options: Optional[EndpointOptions] = None, ) -> None: + global _stubs_list self.endpoint = endpoint self.endpoint_key = EndpointKey(self.endpoint, getattr(endpoint_options, "node_id", None)) self.node_id = getattr(endpoint_options, "node_id", None) diff --git a/ydb/connection.py b/ydb/connection.py index 6ac700b8..fc05544b 100644 --- a/ydb/connection.py +++ b/ydb/connection.py @@ -416,6 +416,7 @@ def __init__( discovered by the YDB endpoint discovery mechanism :param driver_config: A driver config instance to be used for RPC call interception """ + global _stubs_list self.endpoint = endpoint self.node_id = getattr(endpoint_options, "node_id", None) self.endpoint_key = EndpointKey(endpoint, getattr(endpoint_options, "node_id", None)) diff --git a/ydb/retries.py b/ydb/retries.py index c151e3d2..0b3bec52 100644 --- a/ydb/retries.py +++ b/ydb/retries.py @@ -77,7 +77,7 @@ def __init__(self, timeout: float) -> None: def __eq__(self, other: object) -> bool: return ( - type(self) is type(other) and isinstance(other, YdbRetryOperationSleepOpt) and self.timeout == other.timeout + type(self) == type(other) and isinstance(other, YdbRetryOperationSleepOpt) and self.timeout == other.timeout ) def __repr__(self) -> str: @@ -91,7 +91,7 @@ def __init__(self, result: Any) -> None: def __eq__(self, other: object) -> bool: return ( - type(self) is type(other) + type(self) == type(other) and isinstance(other, YdbRetryOperationFinalResult) and self.result == other.result and self.exc == other.exc diff --git a/ydb/table_test.py b/ydb/table_test.py index b365fda1..d5d86e05 100644 --- a/ydb/table_test.py +++ b/ydb/table_test.py @@ -14,7 +14,7 @@ def test_retry_operation_impl(monkeypatch): monkeypatch.setattr( issues.Error, "__eq__", - lambda self, other: type(self) is type(other) and self.message == other.message, + lambda self, other: type(self) == type(other) and self.message == other.message, ) retry_once_settings = RetrySettings( @@ -43,7 +43,7 @@ def __init__(self, message): self.message = message def __eq__(self, other): - return type(self) is type(other) and self.message == other.message + return type(self) == type(other) and self.message == other.message def check_unretriable_error(err_type, call_ydb_handler): retry_once_settings.on_ydb_error_callback.reset_mock() From 427e6ec343d1dcb779f3c97bb3524e7ffaecfea4 Mon Sep 17 00:00:00 2001 From: Oleg Ovcharuk Date: Thu, 5 Feb 2026 16:48:02 +0300 Subject: [PATCH 5/5] fix style --- examples/coordination/example.py | 2 +- examples/topic/writer_example.py | 2 +- tests/iam/test_auth.py | 2 +- tests/scheme/scheme_test.py | 2 +- tests/test_errors.py | 2 +- tests/topics/test_topic_writer.py | 2 +- ydb/retries.py | 4 ++-- ydb/table_test.py | 4 ++-- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/coordination/example.py b/examples/coordination/example.py index 0b817ff3..42f89fe6 100644 --- a/examples/coordination/example.py +++ b/examples/coordination/example.py @@ -43,7 +43,7 @@ def run(endpoint, database): threads = [] for i in range(4): - worker_name = f"worker {i+1}" + worker_name = f"worker {i + 1}" if i < 2: thread = threading.Thread(target=linear_workload, args=(driver.coordination_client, worker_name)) else: diff --git a/examples/topic/writer_example.py b/examples/topic/writer_example.py index b122e78c..99346a27 100644 --- a/examples/topic/writer_example.py +++ b/examples/topic/writer_example.py @@ -1,7 +1,7 @@ import concurrent.futures import datetime from typing import Dict, List -from concurrent.futures import Future, wait +from concurrent.futures import Future, wait # noqa: F401 import ydb from ydb import TopicWriterMessage diff --git a/tests/iam/test_auth.py b/tests/iam/test_auth.py index 54117b53..09a1c03a 100644 --- a/tests/iam/test_auth.py +++ b/tests/iam/test_auth.py @@ -14,7 +14,7 @@ def __init__(self, account_id, key_id, private_key, iam_endpoint=None, iam_chann self.iam_channel_credentials = iam_channel_credentials def __eq__(self, other): - return self.__dict__ == other.__dict__ if type(self) == type(other) else False + return self.__dict__ == other.__dict__ if type(self) is type(other) else False @patch("builtins.open", new_callable=mock_open, read_data=CONTENT1) diff --git a/tests/scheme/scheme_test.py b/tests/scheme/scheme_test.py index 4f93c8ea..1a105620 100644 --- a/tests/scheme/scheme_test.py +++ b/tests/scheme/scheme_test.py @@ -1,4 +1,4 @@ -import typing +import typing # noqa: F401 import pytest import ydb diff --git a/tests/test_errors.py b/tests/test_errors.py index 93f6f4a3..bdecebef 100644 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -11,7 +11,7 @@ def test_scheme_error(driver_sync, database): server_code = ydb.issues.StatusCode.SCHEME_ERROR - assert type(exc.value) == ydb.issues.SchemeError + assert type(exc.value) is ydb.issues.SchemeError assert exc.value.status == server_code assert f"server_code: {server_code}" in str(exc.value) assert "Path does not exist" in str(exc.value) diff --git a/tests/topics/test_topic_writer.py b/tests/topics/test_topic_writer.py index aed552ab..df729e96 100644 --- a/tests/topics/test_topic_writer.py +++ b/tests/topics/test_topic_writer.py @@ -1,7 +1,7 @@ from __future__ import annotations import asyncio -from typing import List +from typing import List # noqa: F401 import pytest diff --git a/ydb/retries.py b/ydb/retries.py index 0b3bec52..c151e3d2 100644 --- a/ydb/retries.py +++ b/ydb/retries.py @@ -77,7 +77,7 @@ def __init__(self, timeout: float) -> None: def __eq__(self, other: object) -> bool: return ( - type(self) == type(other) and isinstance(other, YdbRetryOperationSleepOpt) and self.timeout == other.timeout + type(self) is type(other) and isinstance(other, YdbRetryOperationSleepOpt) and self.timeout == other.timeout ) def __repr__(self) -> str: @@ -91,7 +91,7 @@ def __init__(self, result: Any) -> None: def __eq__(self, other: object) -> bool: return ( - type(self) == type(other) + type(self) is type(other) and isinstance(other, YdbRetryOperationFinalResult) and self.result == other.result and self.exc == other.exc diff --git a/ydb/table_test.py b/ydb/table_test.py index d5d86e05..b365fda1 100644 --- a/ydb/table_test.py +++ b/ydb/table_test.py @@ -14,7 +14,7 @@ def test_retry_operation_impl(monkeypatch): monkeypatch.setattr( issues.Error, "__eq__", - lambda self, other: type(self) == type(other) and self.message == other.message, + lambda self, other: type(self) is type(other) and self.message == other.message, ) retry_once_settings = RetrySettings( @@ -43,7 +43,7 @@ def __init__(self, message): self.message = message def __eq__(self, other): - return type(self) == type(other) and self.message == other.message + return type(self) is type(other) and self.message == other.message def check_unretriable_error(err_type, call_ydb_handler): retry_once_settings.on_ydb_error_callback.reset_mock()