csu 2.4.0__tar.gz → 2.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. {csu-2.4.0 → csu-2.4.2}/.bumpversion.cfg +1 -1
  2. {csu-2.4.0 → csu-2.4.2}/.cookiecutterrc +1 -1
  3. {csu-2.4.0 → csu-2.4.2}/PKG-INFO +3 -3
  4. {csu-2.4.0 → csu-2.4.2}/README.rst +2 -2
  5. {csu-2.4.0 → csu-2.4.2}/pyproject.toml +1 -1
  6. {csu-2.4.0 → csu-2.4.2}/src/csu/__init__.py +1 -1
  7. {csu-2.4.0 → csu-2.4.2}/src/csu/service.py +25 -19
  8. {csu-2.4.0 → csu-2.4.2}/src/csu.egg-info/PKG-INFO +3 -3
  9. {csu-2.4.0 → csu-2.4.2}/tests/test_service.py +16 -18
  10. {csu-2.4.0 → csu-2.4.2}/.coveragerc +0 -0
  11. {csu-2.4.0 → csu-2.4.2}/.editorconfig +0 -0
  12. {csu-2.4.0 → csu-2.4.2}/.github/workflows/github-actions.yml +0 -0
  13. {csu-2.4.0 → csu-2.4.2}/.pre-commit-config.yaml +0 -0
  14. {csu-2.4.0 → csu-2.4.2}/.tombi.toml +0 -0
  15. {csu-2.4.0 → csu-2.4.2}/AUTHORS.rst +0 -0
  16. {csu-2.4.0 → csu-2.4.2}/CHANGELOG.rst +0 -0
  17. {csu-2.4.0 → csu-2.4.2}/CONTRIBUTING.rst +0 -0
  18. {csu-2.4.0 → csu-2.4.2}/LICENSE +0 -0
  19. {csu-2.4.0 → csu-2.4.2}/MANIFEST.in +0 -0
  20. {csu-2.4.0 → csu-2.4.2}/ci/bootstrap.py +0 -0
  21. {csu-2.4.0 → csu-2.4.2}/ci/requirements.txt +0 -0
  22. {csu-2.4.0 → csu-2.4.2}/ci/templates/.github/workflows/github-actions.yml +0 -0
  23. {csu-2.4.0 → csu-2.4.2}/pytest.ini +0 -0
  24. {csu-2.4.0 → csu-2.4.2}/setup.cfg +0 -0
  25. {csu-2.4.0 → csu-2.4.2}/src/csu/admin.py +0 -0
  26. {csu-2.4.0 → csu-2.4.2}/src/csu/conf.py +0 -0
  27. {csu-2.4.0 → csu-2.4.2}/src/csu/consts.py +0 -0
  28. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/__init__.py +0 -0
  29. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/auth.py +0 -0
  30. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/fields.py +0 -0
  31. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/forms.py +0 -0
  32. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/perms.py +0 -0
  33. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/phonenumber.py +0 -0
  34. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/serializers.py +0 -0
  35. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/test_auth.py +0 -0
  36. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/test_fields.py +0 -0
  37. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/test_forms.py +0 -0
  38. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/test_phonenumber.py +0 -0
  39. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/test_serializers.py +0 -0
  40. {csu-2.4.0 → csu-2.4.2}/src/csu/drf/views.py +0 -0
  41. {csu-2.4.0 → csu-2.4.2}/src/csu/enums.py +0 -0
  42. {csu-2.4.0 → csu-2.4.2}/src/csu/env.py +0 -0
  43. {csu-2.4.0 → csu-2.4.2}/src/csu/exceptions.py +0 -0
  44. {csu-2.4.0 → csu-2.4.2}/src/csu/export.py +0 -0
  45. {csu-2.4.0 → csu-2.4.2}/src/csu/fixups.py +0 -0
  46. {csu-2.4.0 → csu-2.4.2}/src/csu/forms/__init__.py +0 -0
  47. {csu-2.4.0 → csu-2.4.2}/src/csu/forms/crispy.py +0 -0
  48. {csu-2.4.0 → csu-2.4.2}/src/csu/forms/fields.py +0 -0
  49. {csu-2.4.0 → csu-2.4.2}/src/csu/gettext.py +0 -0
  50. {csu-2.4.0 → csu-2.4.2}/src/csu/gettext_lazy.py +0 -0
  51. {csu-2.4.0 → csu-2.4.2}/src/csu/locale/ro/LC_MESSAGES/django.mo +0 -0
  52. {csu-2.4.0 → csu-2.4.2}/src/csu/locale/ro/LC_MESSAGES/django.po +0 -0
  53. {csu-2.4.0 → csu-2.4.2}/src/csu/logging.py +0 -0
  54. {csu-2.4.0 → csu-2.4.2}/src/csu/management.py +0 -0
  55. {csu-2.4.0 → csu-2.4.2}/src/csu/models.py +0 -0
  56. {csu-2.4.0 → csu-2.4.2}/src/csu/query.py +0 -0
  57. {csu-2.4.0 → csu-2.4.2}/src/csu/routers.py +0 -0
  58. {csu-2.4.0 → csu-2.4.2}/src/csu/templates/api_exception.html +0 -0
  59. {csu-2.4.0 → csu-2.4.2}/src/csu/templates/forms/widgets/opaquewidget.html +0 -0
  60. {csu-2.4.0 → csu-2.4.2}/src/csu/test_consts.py +0 -0
  61. {csu-2.4.0 → csu-2.4.2}/src/csu/test_env.py +0 -0
  62. {csu-2.4.0 → csu-2.4.2}/src/csu/test_exceptions.py +0 -0
  63. {csu-2.4.0 → csu-2.4.2}/src/csu/test_logging.py +0 -0
  64. {csu-2.4.0 → csu-2.4.2}/src/csu/test_management.py +0 -0
  65. {csu-2.4.0 → csu-2.4.2}/src/csu/test_service.py +0 -0
  66. {csu-2.4.0 → csu-2.4.2}/src/csu/test_timezones.py +0 -0
  67. {csu-2.4.0 → csu-2.4.2}/src/csu/test_utils.py +0 -0
  68. {csu-2.4.0 → csu-2.4.2}/src/csu/test_xml.py +0 -0
  69. {csu-2.4.0 → csu-2.4.2}/src/csu/timezones.py +0 -0
  70. {csu-2.4.0 → csu-2.4.2}/src/csu/utils.py +0 -0
  71. {csu-2.4.0 → csu-2.4.2}/src/csu/views.py +0 -0
  72. {csu-2.4.0 → csu-2.4.2}/src/csu/worker/__init__.py +0 -0
  73. {csu-2.4.0 → csu-2.4.2}/src/csu/worker/admin.py +0 -0
  74. {csu-2.4.0 → csu-2.4.2}/src/csu/worker/asgi.py +0 -0
  75. {csu-2.4.0 → csu-2.4.2}/src/csu/worker/engine.py +0 -0
  76. {csu-2.4.0 → csu-2.4.2}/src/csu/worker/enums.py +0 -0
  77. {csu-2.4.0 → csu-2.4.2}/src/csu/worker/job.py +0 -0
  78. {csu-2.4.0 → csu-2.4.2}/src/csu/worker/models.py +0 -0
  79. {csu-2.4.0 → csu-2.4.2}/src/csu/worker/registry.py +0 -0
  80. {csu-2.4.0 → csu-2.4.2}/src/csu/wsgi.py +0 -0
  81. {csu-2.4.0 → csu-2.4.2}/src/csu/xml.py +0 -0
  82. {csu-2.4.0 → csu-2.4.2}/src/csu.egg-info/SOURCES.txt +0 -0
  83. {csu-2.4.0 → csu-2.4.2}/src/csu.egg-info/dependency_links.txt +0 -0
  84. {csu-2.4.0 → csu-2.4.2}/src/csu.egg-info/requires.txt +0 -0
  85. {csu-2.4.0 → csu-2.4.2}/src/csu.egg-info/top_level.txt +0 -0
  86. {csu-2.4.0 → csu-2.4.2}/tests/cassettes/test_service/test_custom_context.yaml +0 -0
  87. {csu-2.4.0 → csu-2.4.2}/tests/cassettes/test_service/test_custom_context_0_retries.yaml +0 -0
  88. {csu-2.4.0 → csu-2.4.2}/tests/cassettes/test_service/test_decoding.yaml +0 -0
  89. {csu-2.4.0 → csu-2.4.2}/tests/cassettes/test_service/test_error.yaml +0 -0
  90. {csu-2.4.0 → csu-2.4.2}/tests/cassettes/test_service/test_logging.yaml +0 -0
  91. {csu-2.4.0 → csu-2.4.2}/tests/cassettes/test_service/test_redirects.yaml +0 -0
  92. {csu-2.4.0 → csu-2.4.2}/tests/cassettes/test_service_auth/test_async.yaml +0 -0
  93. {csu-2.4.0 → csu-2.4.2}/tests/cassettes/test_service_auth/test_async_auth.yaml +0 -0
  94. {csu-2.4.0 → csu-2.4.2}/tests/cassettes/test_service_auth/test_sync.yaml +0 -0
  95. {csu-2.4.0 → csu-2.4.2}/tests/cassettes/test_service_auth/test_sync_auth.yaml +0 -0
  96. {csu-2.4.0 → csu-2.4.2}/tests/conftest.py +0 -0
  97. {csu-2.4.0 → csu-2.4.2}/tests/exampleworker.py +0 -0
  98. {csu-2.4.0 → csu-2.4.2}/tests/test_exampleworker.py +0 -0
  99. {csu-2.4.0 → csu-2.4.2}/tests/test_models.py +0 -0
  100. {csu-2.4.0 → csu-2.4.2}/tests/test_service_auth.py +0 -0
  101. {csu-2.4.0 → csu-2.4.2}/tests/test_views.py +0 -0
  102. {csu-2.4.0 → csu-2.4.2}/tests/test_worker.py +0 -0
  103. {csu-2.4.0 → csu-2.4.2}/tests/testproject/__init__.py +0 -0
  104. {csu-2.4.0 → csu-2.4.2}/tests/testproject/fixtures/testuser.json +0 -0
  105. {csu-2.4.0 → csu-2.4.2}/tests/testproject/models.py +0 -0
  106. {csu-2.4.0 → csu-2.4.2}/tests/testproject/settings.py +0 -0
  107. {csu-2.4.0 → csu-2.4.2}/tests/testproject/urls.py +0 -0
  108. {csu-2.4.0 → csu-2.4.2}/tox.ini +0 -0
@@ -1,5 +1,5 @@
1
1
  [bumpversion]
2
- current_version = 2.4.0
2
+ current_version = 2.4.2
3
3
  commit = True
4
4
  tag = True
5
5
 
@@ -41,7 +41,7 @@ default_context:
41
41
  sphinx_theme: furo
42
42
  test_matrix_separate_coverage: false
43
43
  tests_inside_package: true
44
- version: 2.4.0
44
+ version: 2.4.2
45
45
  version_manager: bump2version
46
46
  website: https://blog.ionelmc.ro
47
47
  year_from: '2024'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csu
3
- Version: 2.4.0
3
+ Version: 2.4.2
4
4
  Summary: Clean Slate Utils - bunch of utility code, mostly Django/DRF specific.
5
5
  Author-email: Ionel Cristian Mărieș <contact@ionelmc.ro>
6
6
  License-Expression: BSD-2-Clause
@@ -69,9 +69,9 @@ Overview
69
69
  .. |supported-implementations| image:: https://img.shields.io/pypi/implementation/csu.svg
70
70
  :alt: Supported implementations
71
71
  :target: https://pypi.org/project/csu
72
- .. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-csu/v2.4.0.svg
72
+ .. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-csu/v2.4.2.svg
73
73
  :alt: Commits since latest release
74
- :target: https://github.com/ionelmc/python-csu/compare/v2.4.0...main
74
+ :target: https://github.com/ionelmc/python-csu/compare/v2.4.2...main
75
75
  .. |scrutinizer| image:: https://img.shields.io/scrutinizer/quality/g/ionelmc/python-csu/main.svg
76
76
  :alt: Scrutinizer Status
77
77
  :target: https://scrutinizer-ci.com/g/ionelmc/python-csu/
@@ -34,9 +34,9 @@ Overview
34
34
  .. |supported-implementations| image:: https://img.shields.io/pypi/implementation/csu.svg
35
35
  :alt: Supported implementations
36
36
  :target: https://pypi.org/project/csu
37
- .. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-csu/v2.4.0.svg
37
+ .. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-csu/v2.4.2.svg
38
38
  :alt: Commits since latest release
39
- :target: https://github.com/ionelmc/python-csu/compare/v2.4.0...main
39
+ :target: https://github.com/ionelmc/python-csu/compare/v2.4.2...main
40
40
  .. |scrutinizer| image:: https://img.shields.io/scrutinizer/quality/g/ionelmc/python-csu/main.svg
41
41
  :alt: Scrutinizer Status
42
42
  :target: https://scrutinizer-ci.com/g/ionelmc/python-csu/
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "csu"
3
- version = "2.4.0"
3
+ version = "2.4.2"
4
4
  description = "Clean Slate Utils - bunch of utility code, mostly Django/DRF specific."
5
5
  requires-python = ">=3.14"
6
6
  license = "BSD-2-Clause"
@@ -2,4 +2,4 @@
2
2
  a.k.a Clean Slate Utils
3
3
  """
4
4
 
5
- __version__ = "2.4.0"
5
+ __version__ = "2.4.2"
@@ -1,6 +1,5 @@
1
1
  import os
2
2
  from collections.abc import Iterable
3
- from dataclasses import dataclass
4
3
  from decimal import Decimal
5
4
  from logging import Logger
6
5
  from logging import getLogger
@@ -16,9 +15,9 @@ from niquests import Response
16
15
  from niquests import Session
17
16
  from niquests.auth import AsyncAuthBase
18
17
  from niquests.auth import AuthBase
18
+ from niquests.exceptions import ConnectionError
19
19
  from niquests.typing import TLSClientCertType
20
20
  from niquests.typing import TLSVerifyType
21
- from urllib3_future.exceptions import RequestError
22
21
 
23
22
  from .conf import SERVICE_REQUEST_CONTENT_LOG_LIMIT
24
23
  from .conf import SERVICE_REQUEST_SHOW_HEADERS
@@ -36,15 +35,25 @@ from .exceptions import UnexpectedStatusError
36
35
  from .exceptions import get_event_id
37
36
 
38
37
 
39
- @dataclass(kw_only=True)
40
38
  class HTTPServiceResponse:
41
39
  status: int
42
40
  http_response: Response | AsyncResponse
43
41
  event_id: str
44
42
  json: None | list | dict = None
43
+ text: str
44
+ content: bytes
45
45
 
46
- def __getattr__(self, name):
47
- return getattr(self.http_response, name)
46
+ def __init__(self, http_response: Response, *, content: bytes, text: str, json=None, event_id=None):
47
+ assert http_response.status_code, f"{http_response=} doesn't have a status code"
48
+ self.status = http_response.status_code
49
+ self.http_response = http_response
50
+ self.event_id = event_id
51
+ self.content = content
52
+ self.text = text
53
+ self.json = json
54
+
55
+ def __repr__(self):
56
+ return f"HTTPServiceResponse({self.status}, {self.content if self.json is None else self.json})"
48
57
 
49
58
 
50
59
  class HTTPServiceAuth(AuthBase):
@@ -223,12 +232,8 @@ class HTTPServiceContext[RTYPE = HTTPServiceResponse]:
223
232
  raise DecodeError(response, exc, event_id=self.event_id) from exc
224
233
  else:
225
234
  json = None
226
- return HTTPServiceResponse(
227
- status=response.status_code,
228
- http_response=response,
229
- json=json,
230
- event_id=self.event_id,
231
- )
235
+
236
+ return HTTPServiceResponse(response, json=json, content=response.content, text=response.text, event_id=self.event_id)
232
237
 
233
238
  def handle_prepare_request(
234
239
  self,
@@ -265,6 +270,7 @@ class HTTPServiceContext[RTYPE = HTTPServiceResponse]:
265
270
  expect_json: bool = True,
266
271
  follow_redirects: bool = False,
267
272
  retry_statuses: Iterable[int] = (500, 502, 503, 504),
273
+ retry_exceptions: Iterable[type[Exception]] = (ConnectionError, RetryableError),
268
274
  retry: bool = True,
269
275
  proxy: str | None = None,
270
276
  stream: bool | None = None,
@@ -300,7 +306,7 @@ class HTTPServiceContext[RTYPE = HTTPServiceResponse]:
300
306
  elif response.status_code not in accept_statuses:
301
307
  raise UnexpectedStatusError(response, accept_statuses, event_id=self.event_id)
302
308
  return self.handle_process_response(response, expect_json=expect_json)
303
- except (RequestError, RetryableError) as exc:
309
+ except retry_exceptions as exc:
304
310
  retry_failures.append(exc)
305
311
  self.handle_retriable_failure(method, prepared_request.url, exc, retries_left, retry_budget)
306
312
  except (InternalServiceError, OpenServiceError) as exc:
@@ -342,18 +348,17 @@ class AsyncHTTPServiceContext[RTYPE = HTTPServiceResponse](HTTPServiceContext[RT
342
348
  try:
343
349
  if isinstance(response, AsyncResponse):
344
350
  json = await response.json(parse_float=Decimal)
351
+ content = await response.content
352
+ text = await response.text
345
353
  else:
346
354
  json = response.json(parse_float=Decimal)
355
+ content = response.content
356
+ text = response.text
347
357
  except Exception as exc:
348
358
  raise DecodeError(response, exc, event_id=self.event_id) from exc
349
359
  else:
350
360
  json = None
351
- return HTTPServiceResponse(
352
- status=response.status_code,
353
- http_response=response,
354
- json=json,
355
- event_id=self.event_id,
356
- )
361
+ return HTTPServiceResponse(response, content=content, text=text, json=json, event_id=self.event_id)
357
362
 
358
363
  async def request(
359
364
  self,
@@ -364,6 +369,7 @@ class AsyncHTTPServiceContext[RTYPE = HTTPServiceResponse](HTTPServiceContext[RT
364
369
  expect_json: bool = True,
365
370
  follow_redirects: bool = False,
366
371
  retry_statuses: Iterable[int] = (500, 502, 503, 504),
372
+ retry_exceptions: Iterable[type[Exception]] = (ConnectionError, RetryableError),
367
373
  retry: bool = True,
368
374
  proxy: str | None = None,
369
375
  stream: bool | None = None,
@@ -405,7 +411,7 @@ class AsyncHTTPServiceContext[RTYPE = HTTPServiceResponse](HTTPServiceContext[RT
405
411
  elif response.status_code not in accept_statuses:
406
412
  raise UnexpectedStatusError(response, accept_statuses, event_id=self.event_id)
407
413
  return await self.handle_process_response(response, expect_json=expect_json)
408
- except (RequestError, RetryableError) as exc:
414
+ except retry_exceptions as exc:
409
415
  retry_failures.append(exc)
410
416
  self.handle_retriable_failure(method, prepared_request.url, exc, retries_left, retry_budget)
411
417
  except (InternalServiceError, OpenServiceError) as exc:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csu
3
- Version: 2.4.0
3
+ Version: 2.4.2
4
4
  Summary: Clean Slate Utils - bunch of utility code, mostly Django/DRF specific.
5
5
  Author-email: Ionel Cristian Mărieș <contact@ionelmc.ro>
6
6
  License-Expression: BSD-2-Clause
@@ -69,9 +69,9 @@ Overview
69
69
  .. |supported-implementations| image:: https://img.shields.io/pypi/implementation/csu.svg
70
70
  :alt: Supported implementations
71
71
  :target: https://pypi.org/project/csu
72
- .. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-csu/v2.4.0.svg
72
+ .. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-csu/v2.4.2.svg
73
73
  :alt: Commits since latest release
74
- :target: https://github.com/ionelmc/python-csu/compare/v2.4.0...main
74
+ :target: https://github.com/ionelmc/python-csu/compare/v2.4.2...main
75
75
  .. |scrutinizer| image:: https://img.shields.io/scrutinizer/quality/g/ionelmc/python-csu/main.svg
76
76
  :alt: Scrutinizer Status
77
77
  :target: https://scrutinizer-ci.com/g/ionelmc/python-csu/
@@ -154,7 +154,6 @@ def test_error(fake_accident_id, caplogs, httpbin):
154
154
  bingo.error()
155
155
  assert exc.value.message == "It's ok."
156
156
  api_exc = exc.value.as_api_service_error()
157
- exc.value.details[0]
158
157
  assert api_exc.status_code == 200
159
158
  assert api_exc.detail == {"accident_id": "241212:01:000000.00", "code": "ok", "detail": "It's ok."}
160
159
 
@@ -261,7 +260,7 @@ json.decoder.JSONDecodeError: Expecting value: line 2 column 5 (char 5)
261
260
  During handling of the above exception, another exception occurred:
262
261
 
263
262
  Traceback (most recent call last):
264
- File "[&SERVICE_PATH]", line 221, in handle_process_response
263
+ File "[&SERVICE_PATH]", line 230, in handle_process_response
265
264
  json = response.json(parse_float=Decimal)
266
265
  File "[&MODELS_PATH]", line 1529, in json
267
266
  raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
@@ -270,16 +269,16 @@ niquests.exceptions.JSONDecodeError: Expecting value: line 2 column 5 (char 5)
270
269
  The above exception was the direct cause of the following exception:
271
270
 
272
271
  Traceback (most recent call last):
273
- File "[&TEST_PATH]", line 203, in test_decoding
272
+ File "[&TEST_PATH]", line 202, in test_decoding
274
273
  bingo.json()
275
274
  ~~~~~~~~~~^^
276
275
  File "[&TEST_PATH]", line 78, in json
277
276
  return ctx.request("GET", "status/418", accept_statuses=[418]).json
278
277
  ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
279
- File "[&SERVICE_PATH]", line 302, in request
278
+ File "[&SERVICE_PATH]", line 308, in request
280
279
  return self.handle_process_response(response, expect_json=expect_json)
281
280
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
282
- File "[&SERVICE_PATH]", line 223, in handle_process_response
281
+ File "[&SERVICE_PATH]", line 232, in handle_process_response
283
282
  raise DecodeError(response, exc, event_id=self.event_id) from exc
284
283
  csu.exceptions.DecodeError: DecodeError(JSONDecodeError('Expecting value: line 2 column 5 (char 5)'), response=<Response Dummy [418]>)
285
284
  (418, b'\\n -=[ teapot ]=-\\n\\n _...._\\n .\\' _ _ `.\\n | ."` ^ `". _,\\n \\\\_;`"---"`|//\\n | ;/\\n \\\\_ _/\\n `"""`\\n')
@@ -296,7 +295,6 @@ def test_logging(fake_accident_id, caplogs, httpbin):
296
295
  bingo = BingoService(httpbin.url)
297
296
  with pytest.raises(OkError) as exc:
298
297
  bingo.error()
299
- exc.value.details[0]
300
298
  exception_handler(exc.value, {})
301
299
  assert len(fake_accident_id.calls) == 1
302
300
  assert fake_accident_id.calls[0].startswith("service.py:")
@@ -342,7 +340,7 @@ Traceback (most recent call last):
342
340
  File "[&TEST_PATH]", line 47, in error
343
341
  return ctx.request("GET", "status/599", expect_json=False)
344
342
  ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
345
- File "[&SERVICE_PATH]", line 301, in request
343
+ File "[&SERVICE_PATH]", line 307, in request
346
344
  raise UnexpectedStatusError(response, accept_statuses, event_id=self.event_id)
347
345
  csu.exceptions.UnexpectedStatusError: UnexpectedStatusError(<Response Dummy [599]>, accept_statuses=[200])
348
346
  (599, b'')
@@ -350,7 +348,7 @@ csu.exceptions.UnexpectedStatusError: UnexpectedStatusError(<Response Dummy [599
350
348
  The above exception was the direct cause of the following exception:
351
349
 
352
350
  Traceback (most recent call last):
353
- File "[&TEST_PATH]", line 298, in test_logging
351
+ File "[&TEST_PATH]", line 297, in test_logging
354
352
  bingo.error()
355
353
  ~~~~~~~~~~~^^
356
354
  File "[&TEST_PATH]", line 50, in error
@@ -542,7 +540,7 @@ INFO | [01:000000.00] POST [&HTTPBIN]/anything?foo=bar&accept_statuses=%7B999
542
540
  """\
543
541
  ERROR | [01:000000.00] POST [&HTTPBIN]/anything?foo=bar&accept_statuses=%7B999%7D&expect_json=true&follow_redirects=false&retries_left=3&retry_count=0&retry_statuses=%7B200%7D !> RetryableStatusError('200 not in [999] but in [200]', 200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"3","retry_count":"0","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=3&retry_count=0&retry_statuses={200}"}\\n', event_id=241212:01:000000.00) (will retry 3 more times)
544
542
  Traceback (most recent call last):
545
- File "[&SERVICE_PATH]", line 299, in request
543
+ File "[&SERVICE_PATH]", line 305, in request
546
544
  raise RetryableStatusError(response, accept_statuses, retry_statuses, event_id=self.event_id)
547
545
  csu.exceptions.RetryableStatusError: RetryableStatusError(<Response Dummy [200]>, accept_statuses=[999], retry_statuses=[200])
548
546
  (200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"3","retry_count":"0","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=3&retry_count=0&retry_statuses={200}"}\\n')
@@ -576,7 +574,7 @@ INFO | [01:000000.00] POST [&HTTPBIN]/anything?foo=bar&accept_statuses=%7B999
576
574
  """\
577
575
  ERROR | [01:000000.00] POST [&HTTPBIN]/anything?foo=bar&accept_statuses=%7B999%7D&expect_json=true&follow_redirects=false&retries_left=2&retry_count=1&retry_statuses=%7B200%7D !> RetryableStatusError('200 not in [999] but in [200]', 200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"2","retry_count":"1","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=2&retry_count=1&retry_statuses={200}"}\\n', event_id=241212:01:000000.00) (will retry 2 more times)
578
576
  Traceback (most recent call last):
579
- File "[&SERVICE_PATH]", line 299, in request
577
+ File "[&SERVICE_PATH]", line 305, in request
580
578
  raise RetryableStatusError(response, accept_statuses, retry_statuses, event_id=self.event_id)
581
579
  csu.exceptions.RetryableStatusError: RetryableStatusError(<Response Dummy [200]>, accept_statuses=[999], retry_statuses=[200])
582
580
  (200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"2","retry_count":"1","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=2&retry_count=1&retry_statuses={200}"}\\n')
@@ -610,7 +608,7 @@ INFO | [01:000000.00] POST [&HTTPBIN]/anything?foo=bar&accept_statuses=%7B999
610
608
  """\
611
609
  ERROR | [01:000000.00] POST [&HTTPBIN]/anything?foo=bar&accept_statuses=%7B999%7D&expect_json=true&follow_redirects=false&retries_left=1&retry_count=2&retry_statuses=%7B200%7D !> RetryableStatusError('200 not in [999] but in [200]', 200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"1","retry_count":"2","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=1&retry_count=2&retry_statuses={200}"}\\n', event_id=241212:01:000000.00) (will retry 1 more times)
612
610
  Traceback (most recent call last):
613
- File "[&SERVICE_PATH]", line 299, in request
611
+ File "[&SERVICE_PATH]", line 305, in request
614
612
  raise RetryableStatusError(response, accept_statuses, retry_statuses, event_id=self.event_id)
615
613
  csu.exceptions.RetryableStatusError: RetryableStatusError(<Response Dummy [200]>, accept_statuses=[999], retry_statuses=[200])
616
614
  (200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"1","retry_count":"2","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=1&retry_count=2&retry_statuses={200}"}\\n')
@@ -649,40 +647,40 @@ ERROR | (renderer: NoneType)
649
647
  {}
650
648
  ---------------------------------------------------------------- traceback -----------------------------------------------------------------
651
649
  + Exception Group Traceback (most recent call last):
652
- | File "[&TEST_PATH]", line 437, in test_custom_context
650
+ | File "[&TEST_PATH]", line 435, in test_custom_context
653
651
  | custom.run()
654
652
  | ~~~~~~~~~~^^
655
- | File "[&TEST_PATH]", line 420, in run
653
+ | File "[&TEST_PATH]", line 418, in run
656
654
  | resp = ctx.request(
657
655
  | "POST",
658
656
  | ...<6 lines>...
659
657
  | accept_statuses=[999],
660
658
  | )
661
- | File "[&SERVICE_PATH]", line 313, in request
659
+ | File "[&SERVICE_PATH]", line 319, in request
662
660
  | raise ExhaustedRetriesError(retry_budget, retry_failures, event_id=self.event_id)
663
661
  | csu.exceptions.ExhaustedRetriesError: ExhaustedRetriesError(3)
664
662
  | ([RetryableStatusError('200 not in [999] but in [200]', 200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"3","retry_count":"0","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=3&retry_count=0&retry_statuses={200}"}\\n', event_id=241212:01:000000.00), RetryableStatusError('200 not in [999] but in [200]', 200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"2","retry_count":"1","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=2&retry_count=1&retry_statuses={200}"}\\n', event_id=241212:01:000000.00), RetryableStatusError('200 not in [999] but in [200]', 200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"1","retry_count":"2","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=1&retry_count=2&retry_statuses={200}"}\\n', event_id=241212:01:000000.00), RetryableStatusError('200 not in [999] but in [200]', 200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"0","retry_count":"3","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=0&retry_count=3&retry_statuses={200}"}\\n', event_id=241212:01:000000.00)],)
665
663
  +-+---------------- 1 ----------------
666
664
  | Traceback (most recent call last):
667
- | File "[&SERVICE_PATH]", line 299, in request
665
+ | File "[&SERVICE_PATH]", line 305, in request
668
666
  | raise RetryableStatusError(response, accept_statuses, retry_statuses, event_id=self.event_id)
669
667
  | csu.exceptions.RetryableStatusError: RetryableStatusError(<Response Dummy [200]>, accept_statuses=[999], retry_statuses=[200])
670
668
  | (200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"3","retry_count":"0","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=3&retry_count=0&retry_statuses={200}"}\\n')
671
669
  +---------------- 2 ----------------
672
670
  | Traceback (most recent call last):
673
- | File "[&SERVICE_PATH]", line 299, in request
671
+ | File "[&SERVICE_PATH]", line 305, in request
674
672
  | raise RetryableStatusError(response, accept_statuses, retry_statuses, event_id=self.event_id)
675
673
  | csu.exceptions.RetryableStatusError: RetryableStatusError(<Response Dummy [200]>, accept_statuses=[999], retry_statuses=[200])
676
674
  | (200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"2","retry_count":"1","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=2&retry_count=1&retry_statuses={200}"}\\n')
677
675
  +---------------- 3 ----------------
678
676
  | Traceback (most recent call last):
679
- | File "[&SERVICE_PATH]", line 299, in request
677
+ | File "[&SERVICE_PATH]", line 305, in request
680
678
  | raise RetryableStatusError(response, accept_statuses, retry_statuses, event_id=self.event_id)
681
679
  | csu.exceptions.RetryableStatusError: RetryableStatusError(<Response Dummy [200]>, accept_statuses=[999], retry_statuses=[200])
682
680
  | (200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"1","retry_count":"2","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=1&retry_count=2&retry_statuses={200}"}\\n')
683
681
  +---------------- 4 ----------------
684
682
  | Traceback (most recent call last):
685
- | File "[&SERVICE_PATH]", line 299, in request
683
+ | File "[&SERVICE_PATH]", line 305, in request
686
684
  | raise RetryableStatusError(response, accept_statuses, retry_statuses, event_id=self.event_id)
687
685
  | csu.exceptions.RetryableStatusError: RetryableStatusError(<Response Dummy [200]>, accept_statuses=[999], retry_statuses=[200])
688
686
  | (200, b'{"args":{"accept_statuses":"{999}","expect_json":"true","follow_redirects":"false","foo":"bar","retries_left":"0","retry_count":"3","retry_statuses":"{200}"},"data":"config={\\'custom\\': \\'config\\'}","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive","Content-Length":"27","Host":"127.0.0.1:12345","User-Agent":"python-httpx/0.X.X"},"json":null,"method":"POST","origin":"127.0.0.1","url":"http://127.0.0.1:12345/anything?foo=bar&accept_statuses={999}&expect_json=true&follow_redirects=false&retries_left=0&retry_count=3&retry_statuses={200}"}\\n')
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes