From 4bab2a0a08b814cb21da76e4e2ce4047c19cdf7b Mon Sep 17 00:00:00 2001 From: Adam Dobrawy Date: Sat, 7 Mar 2026 13:46:01 +0100 Subject: [PATCH] Add context manager support to AnticaptchaClient Enable clean resource cleanup of the underlying requests.Session via `with` statement, `close()`, or `__exit__`. Co-Authored-By: Claude Opus 4.6 --- python_anticaptcha/base.py | 10 ++++++++++ tests/test_base.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/python_anticaptcha/base.py b/python_anticaptcha/base.py index a5188f7..c30e35e 100644 --- a/python_anticaptcha/base.py +++ b/python_anticaptcha/base.py @@ -98,6 +98,16 @@ def __init__( ) self.session = requests.Session() + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.session.close() + return False + + def close(self): + self.session.close() + @property def client_ip(self) -> str: if not hasattr(self, "_client_ip"): diff --git a/tests/test_base.py b/tests/test_base.py index 0582aad..e7b0968 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -149,6 +149,38 @@ def test_timeout_raises(self, mock_sleep): assert "exceeded" in str(exc_info.value).lower() +class TestContextManager: + def test_enter_returns_self(self): + client = AnticaptchaClient("key123") + assert client.__enter__() is client + + def test_exit_closes_session(self): + client = AnticaptchaClient("key123") + with patch.object(client.session, "close") as mock_close: + client.__exit__(None, None, None) + mock_close.assert_called_once() + + def test_close_closes_session(self): + client = AnticaptchaClient("key123") + with patch.object(client.session, "close") as mock_close: + client.close() + mock_close.assert_called_once() + + def test_with_statement(self): + with AnticaptchaClient("key123") as client: + assert isinstance(client, AnticaptchaClient) + session = client.session + with patch.object(session, "close") as mock_close: + # Session was already closed by __exit__, verify it's callable + session.close() + mock_close.assert_called_once() + + def test_exit_returns_false(self): + client = AnticaptchaClient("key123") + result = client.__exit__(None, None, None) + assert result is False + + class TestSnakeCaseAliases: def test_create_task_alias(self): assert AnticaptchaClient.create_task is AnticaptchaClient.createTask