2323IntercomError ,
2424APIStatusError ,
2525APITimeoutError ,
26- APIConnectionError ,
2726APIResponseValidationError ,
2827)
2928from intercom ._base_client import (
@@ -45,14 +44,8 @@ def _get_params(client: BaseClient[Any, Any]) -> dict[str, str]:
4544return dict (url .params )
4645
4746
48- _original_response_init = cast (Any ,httpx .Response .__init__ )# type: ignore
49-
50-
51- def _low_retry_response_init (* args :Any ,** kwargs :Any )-> Any :
52- headers = cast ("list[tuple[bytes, bytes]]" ,kwargs ["headers" ])
53- headers .append ((b"retry-after" ,b"0.1" ))
54-
55- return _original_response_init (* args ,** kwargs )
47+ def _low_retry_timeout (* _args :Any ,** _kwargs :Any )-> float :
48+ return 0.1
5649
5750
5851def _get_open_connections (client :Intercom | AsyncIntercom )-> int :
@@ -702,70 +695,29 @@ def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str
702695calculated = client ._calculate_retry_timeout (remaining_retries ,options ,headers )
703696assert calculated == pytest .approx (timeout ,0.5 * 0.875 )# pyright: ignore[reportUnknownMemberType]
704697
705- @mock .patch ("httpx.Response.__init__" ,_low_retry_response_init )
706- def test_retrying_timeout_errors_doesnt_leak (self )-> None :
707- def raise_for_status (response :httpx .Response )-> None :
708- raise httpx .TimeoutException ("Test timeout error" ,request = response .request )
709-
710- with mock .patch ("httpx.Response.raise_for_status" ,raise_for_status ):
711- with pytest .raises (APITimeoutError ):
712- self .client .get (
713- "/me" ,cast_to = httpx .Response ,options = {"headers" : {"X-Stainless-Streamed-Raw-Response" :"true" }}
714- )
715-
716- assert _get_open_connections (self .client )== 0
717-
718- @mock .patch ("httpx.Response.__init__" ,_low_retry_response_init )
719- def test_retrying_runtime_errors_doesnt_leak (self )-> None :
720- def raise_for_status (_response :httpx .Response )-> None :
721- raise RuntimeError ("Test error" )
722-
723- with mock .patch ("httpx.Response.raise_for_status" ,raise_for_status ):
724- with pytest .raises (APIConnectionError ):
725- self .client .get (
726- "/me" ,cast_to = httpx .Response ,options = {"headers" : {"X-Stainless-Streamed-Raw-Response" :"true" }}
727- )
728-
729- assert _get_open_connections (self .client )== 0
730-
731- @mock .patch ("httpx.Response.__init__" ,_low_retry_response_init )
732- def test_retrying_status_errors_doesnt_leak (self )-> None :
733- def raise_for_status (response :httpx .Response )-> None :
734- response .status_code = 500
735- raise httpx .HTTPStatusError ("Test 500 error" ,response = response ,request = response .request )
698+ @mock .patch ("intercom._base_client.BaseClient._calculate_retry_timeout" ,_low_retry_timeout )
699+ @pytest .mark .respx (base_url = base_url )
700+ def test_retrying_timeout_errors_doesnt_leak (self ,respx_mock :MockRouter )-> None :
701+ respx_mock .get ("/me" ).mock (side_effect = httpx .TimeoutException ("Test timeout error" ))
736702
737- with mock .patch ("httpx.Response.raise_for_status" ,raise_for_status ):
738- with pytest .raises (APIStatusError ):
739- self .client .get (
740- "/me" ,cast_to = httpx .Response ,options = {"headers" : {"X-Stainless-Streamed-Raw-Response" :"true" }}
741- )
703+ with pytest .raises (APITimeoutError ):
704+ self .client .get (
705+ "/me" ,cast_to = httpx .Response ,options = {"headers" : {"X-Stainless-Streamed-Raw-Response" :"true" }}
706+ )
742707
743708assert _get_open_connections (self .client )== 0
744709
710+ @mock .patch ("intercom._base_client.BaseClient._calculate_retry_timeout" ,_low_retry_timeout )
745711@pytest .mark .respx (base_url = base_url )
746- def test_status_error_within_httpx (self ,respx_mock :MockRouter )-> None :
747- respx_mock .post ("/foo " ).mock (return_value = httpx .Response (200 , json = { "foo" : "bar" } ))
712+ def test_retrying_status_errors_doesnt_leak (self ,respx_mock :MockRouter )-> None :
713+ respx_mock .get ("/me " ).mock (return_value = httpx .Response (500 ))
748714
749- def on_response (response :httpx .Response )-> None :
750- raise httpx .HTTPStatusError (
751- "Simulating an error inside httpx" ,
752- response = response ,
753- request = response .request ,
715+ with pytest .raises (APIStatusError ):
716+ self .client .get (
717+ "/me" ,cast_to = httpx .Response ,options = {"headers" : {"X-Stainless-Streamed-Raw-Response" :"true" }}
754718 )
755719
756- client = Intercom (
757- base_url = base_url ,
758- bearer_token = bearer_token ,
759- _strict_response_validation = True ,
760- http_client = httpx .Client (
761- event_hooks = {
762- "response" : [on_response ],
763- }
764- ),
765- max_retries = 0 ,
766- )
767- with pytest .raises (APIStatusError ):
768- client .post ("/foo" ,cast_to = httpx .Response )
720+ assert _get_open_connections (self .client )== 0
769721
770722
771723class TestAsyncIntercom :
@@ -1413,68 +1365,26 @@ async def test_parse_retry_after_header(self, remaining_retries: int, retry_afte
14131365calculated = client ._calculate_retry_timeout (remaining_retries ,options ,headers )
14141366assert calculated == pytest .approx (timeout ,0.5 * 0.875 )# pyright: ignore[reportUnknownMemberType]
14151367
1416- @mock .patch ("httpx.Response.__init__" ,_low_retry_response_init )
1417- async def test_retrying_timeout_errors_doesnt_leak (self )-> None :
1418- def raise_for_status (response :httpx .Response )-> None :
1419- raise httpx .TimeoutException ("Test timeout error" ,request = response .request )
1420-
1421- with mock .patch ("httpx.Response.raise_for_status" ,raise_for_status ):
1422- with pytest .raises (APITimeoutError ):
1423- await self .client .get (
1424- "/me" ,cast_to = httpx .Response ,options = {"headers" : {"X-Stainless-Streamed-Raw-Response" :"true" }}
1425- )
1426-
1427- assert _get_open_connections (self .client )== 0
1428-
1429- @mock .patch ("httpx.Response.__init__" ,_low_retry_response_init )
1430- async def test_retrying_runtime_errors_doesnt_leak (self )-> None :
1431- def raise_for_status (_response :httpx .Response )-> None :
1432- raise RuntimeError ("Test error" )
1433-
1434- with mock .patch ("httpx.Response.raise_for_status" ,raise_for_status ):
1435- with pytest .raises (APIConnectionError ):
1436- await self .client .get (
1437- "/me" ,cast_to = httpx .Response ,options = {"headers" : {"X-Stainless-Streamed-Raw-Response" :"true" }}
1438- )
1439-
1440- assert _get_open_connections (self .client )== 0
1441-
1442- @mock .patch ("httpx.Response.__init__" ,_low_retry_response_init )
1443- async def test_retrying_status_errors_doesnt_leak (self )-> None :
1444- def raise_for_status (response :httpx .Response )-> None :
1445- response .status_code = 500
1446- raise httpx .HTTPStatusError ("Test 500 error" ,response = response ,request = response .request )
1368+ @mock .patch ("intercom._base_client.BaseClient._calculate_retry_timeout" ,_low_retry_timeout )
1369+ @pytest .mark .respx (base_url = base_url )
1370+ async def test_retrying_timeout_errors_doesnt_leak (self ,respx_mock :MockRouter )-> None :
1371+ respx_mock .get ("/me" ).mock (side_effect = httpx .TimeoutException ("Test timeout error" ))
14471372
1448- with mock .patch ("httpx.Response.raise_for_status" ,raise_for_status ):
1449- with pytest .raises (APIStatusError ):
1450- await self .client .get (
1451- "/me" ,cast_to = httpx .Response ,options = {"headers" : {"X-Stainless-Streamed-Raw-Response" :"true" }}
1452- )
1373+ with pytest .raises (APITimeoutError ):
1374+ await self .client .get (
1375+ "/me" ,cast_to = httpx .Response ,options = {"headers" : {"X-Stainless-Streamed-Raw-Response" :"true" }}
1376+ )
14531377
14541378assert _get_open_connections (self .client )== 0
14551379
1380+ @mock .patch ("intercom._base_client.BaseClient._calculate_retry_timeout" ,_low_retry_timeout )
14561381@pytest .mark .respx (base_url = base_url )
1457- @pytest .mark .asyncio
1458- async def test_status_error_within_httpx (self ,respx_mock :MockRouter )-> None :
1459- respx_mock .post ("/foo" ).mock (return_value = httpx .Response (200 ,json = {"foo" :"bar" }))
1382+ async def test_retrying_status_errors_doesnt_leak (self ,respx_mock :MockRouter )-> None :
1383+ respx_mock .get ("/me" ).mock (return_value = httpx .Response (500 ))
14601384
1461- def on_response (response :httpx .Response )-> None :
1462- raise httpx .HTTPStatusError (
1463- "Simulating an error inside httpx" ,
1464- response = response ,
1465- request = response .request ,
1385+ with pytest .raises (APIStatusError ):
1386+ await self .client .get (
1387+ "/me" ,cast_to = httpx .Response ,options = {"headers" : {"X-Stainless-Streamed-Raw-Response" :"true" }}
14661388 )
14671389
1468- client = AsyncIntercom (
1469- base_url = base_url ,
1470- bearer_token = bearer_token ,
1471- _strict_response_validation = True ,
1472- http_client = httpx .AsyncClient (
1473- event_hooks = {
1474- "response" : [on_response ],
1475- }
1476- ),
1477- max_retries = 0 ,
1478- )
1479- with pytest .raises (APIStatusError ):
1480- await client .post ("/foo" ,cast_to = httpx .Response )
1390+ assert _get_open_connections (self .client )== 0