sentry-sdk 3.0.0a2__py2.py3-none-any.whl → 3.0.0a3__py2.py3-none-any.whl

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.

Potentially problematic release.


This version of sentry-sdk might be problematic. Click here for more details.

Files changed (157) hide show
  1. sentry_sdk/__init__.py +2 -0
  2. sentry_sdk/_compat.py +5 -12
  3. sentry_sdk/_init_implementation.py +7 -7
  4. sentry_sdk/_log_batcher.py +17 -29
  5. sentry_sdk/_lru_cache.py +7 -9
  6. sentry_sdk/_queue.py +2 -4
  7. sentry_sdk/_types.py +9 -16
  8. sentry_sdk/_werkzeug.py +5 -7
  9. sentry_sdk/ai/monitoring.py +40 -28
  10. sentry_sdk/ai/utils.py +3 -4
  11. sentry_sdk/api.py +75 -87
  12. sentry_sdk/attachments.py +10 -12
  13. sentry_sdk/client.py +110 -153
  14. sentry_sdk/consts.py +398 -220
  15. sentry_sdk/crons/api.py +16 -17
  16. sentry_sdk/crons/decorator.py +25 -27
  17. sentry_sdk/debug.py +4 -6
  18. sentry_sdk/envelope.py +46 -112
  19. sentry_sdk/feature_flags.py +9 -15
  20. sentry_sdk/integrations/__init__.py +24 -19
  21. sentry_sdk/integrations/_asgi_common.py +16 -18
  22. sentry_sdk/integrations/_wsgi_common.py +22 -33
  23. sentry_sdk/integrations/aiohttp.py +32 -30
  24. sentry_sdk/integrations/anthropic.py +42 -37
  25. sentry_sdk/integrations/argv.py +3 -4
  26. sentry_sdk/integrations/ariadne.py +16 -18
  27. sentry_sdk/integrations/arq.py +19 -28
  28. sentry_sdk/integrations/asgi.py +63 -37
  29. sentry_sdk/integrations/asyncio.py +14 -16
  30. sentry_sdk/integrations/atexit.py +6 -10
  31. sentry_sdk/integrations/aws_lambda.py +26 -36
  32. sentry_sdk/integrations/beam.py +10 -18
  33. sentry_sdk/integrations/boto3.py +18 -16
  34. sentry_sdk/integrations/bottle.py +25 -34
  35. sentry_sdk/integrations/celery/__init__.py +36 -56
  36. sentry_sdk/integrations/celery/beat.py +22 -26
  37. sentry_sdk/integrations/celery/utils.py +15 -17
  38. sentry_sdk/integrations/chalice.py +8 -10
  39. sentry_sdk/integrations/clickhouse_driver.py +21 -31
  40. sentry_sdk/integrations/cloud_resource_context.py +9 -16
  41. sentry_sdk/integrations/cohere.py +17 -23
  42. sentry_sdk/integrations/dedupe.py +5 -8
  43. sentry_sdk/integrations/django/__init__.py +57 -72
  44. sentry_sdk/integrations/django/asgi.py +24 -32
  45. sentry_sdk/integrations/django/caching.py +23 -19
  46. sentry_sdk/integrations/django/middleware.py +17 -20
  47. sentry_sdk/integrations/django/signals_handlers.py +11 -10
  48. sentry_sdk/integrations/django/templates.py +19 -16
  49. sentry_sdk/integrations/django/transactions.py +16 -11
  50. sentry_sdk/integrations/django/views.py +6 -10
  51. sentry_sdk/integrations/dramatiq.py +21 -21
  52. sentry_sdk/integrations/excepthook.py +10 -10
  53. sentry_sdk/integrations/executing.py +3 -4
  54. sentry_sdk/integrations/falcon.py +27 -42
  55. sentry_sdk/integrations/fastapi.py +13 -16
  56. sentry_sdk/integrations/flask.py +31 -38
  57. sentry_sdk/integrations/gcp.py +13 -16
  58. sentry_sdk/integrations/gnu_backtrace.py +4 -6
  59. sentry_sdk/integrations/gql.py +16 -17
  60. sentry_sdk/integrations/graphene.py +13 -12
  61. sentry_sdk/integrations/grpc/__init__.py +3 -2
  62. sentry_sdk/integrations/grpc/aio/server.py +15 -14
  63. sentry_sdk/integrations/grpc/client.py +19 -9
  64. sentry_sdk/integrations/grpc/consts.py +2 -0
  65. sentry_sdk/integrations/grpc/server.py +12 -8
  66. sentry_sdk/integrations/httpx.py +9 -12
  67. sentry_sdk/integrations/huey.py +13 -20
  68. sentry_sdk/integrations/huggingface_hub.py +16 -16
  69. sentry_sdk/integrations/langchain.py +203 -113
  70. sentry_sdk/integrations/launchdarkly.py +13 -10
  71. sentry_sdk/integrations/litestar.py +37 -35
  72. sentry_sdk/integrations/logging.py +28 -35
  73. sentry_sdk/integrations/loguru.py +15 -19
  74. sentry_sdk/integrations/modules.py +3 -4
  75. sentry_sdk/integrations/openai.py +96 -84
  76. sentry_sdk/integrations/openai_agents/__init__.py +49 -0
  77. sentry_sdk/integrations/openai_agents/consts.py +1 -0
  78. sentry_sdk/integrations/openai_agents/patches/__init__.py +4 -0
  79. sentry_sdk/integrations/openai_agents/patches/agent_run.py +152 -0
  80. sentry_sdk/integrations/openai_agents/patches/models.py +52 -0
  81. sentry_sdk/integrations/openai_agents/patches/runner.py +42 -0
  82. sentry_sdk/integrations/openai_agents/patches/tools.py +84 -0
  83. sentry_sdk/integrations/openai_agents/spans/__init__.py +5 -0
  84. sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +20 -0
  85. sentry_sdk/integrations/openai_agents/spans/ai_client.py +46 -0
  86. sentry_sdk/integrations/openai_agents/spans/execute_tool.py +47 -0
  87. sentry_sdk/integrations/openai_agents/spans/handoff.py +24 -0
  88. sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +41 -0
  89. sentry_sdk/integrations/openai_agents/utils.py +201 -0
  90. sentry_sdk/integrations/openfeature.py +11 -6
  91. sentry_sdk/integrations/pure_eval.py +6 -10
  92. sentry_sdk/integrations/pymongo.py +13 -17
  93. sentry_sdk/integrations/pyramid.py +31 -36
  94. sentry_sdk/integrations/quart.py +23 -28
  95. sentry_sdk/integrations/ray.py +73 -64
  96. sentry_sdk/integrations/redis/__init__.py +7 -4
  97. sentry_sdk/integrations/redis/_async_common.py +15 -9
  98. sentry_sdk/integrations/redis/_sync_common.py +13 -12
  99. sentry_sdk/integrations/redis/modules/caches.py +17 -8
  100. sentry_sdk/integrations/redis/modules/queries.py +9 -8
  101. sentry_sdk/integrations/redis/rb.py +3 -2
  102. sentry_sdk/integrations/redis/redis.py +4 -4
  103. sentry_sdk/integrations/redis/redis_cluster.py +10 -8
  104. sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +3 -2
  105. sentry_sdk/integrations/redis/utils.py +21 -22
  106. sentry_sdk/integrations/rq.py +13 -16
  107. sentry_sdk/integrations/rust_tracing.py +9 -6
  108. sentry_sdk/integrations/sanic.py +34 -46
  109. sentry_sdk/integrations/serverless.py +22 -27
  110. sentry_sdk/integrations/socket.py +27 -15
  111. sentry_sdk/integrations/spark/__init__.py +1 -0
  112. sentry_sdk/integrations/spark/spark_driver.py +45 -83
  113. sentry_sdk/integrations/spark/spark_worker.py +7 -11
  114. sentry_sdk/integrations/sqlalchemy.py +22 -19
  115. sentry_sdk/integrations/starlette.py +86 -90
  116. sentry_sdk/integrations/starlite.py +28 -34
  117. sentry_sdk/integrations/statsig.py +5 -4
  118. sentry_sdk/integrations/stdlib.py +28 -24
  119. sentry_sdk/integrations/strawberry.py +62 -49
  120. sentry_sdk/integrations/sys_exit.py +7 -11
  121. sentry_sdk/integrations/threading.py +12 -14
  122. sentry_sdk/integrations/tornado.py +28 -32
  123. sentry_sdk/integrations/trytond.py +4 -3
  124. sentry_sdk/integrations/typer.py +8 -6
  125. sentry_sdk/integrations/unleash.py +5 -4
  126. sentry_sdk/integrations/wsgi.py +47 -46
  127. sentry_sdk/logger.py +13 -9
  128. sentry_sdk/monitor.py +16 -28
  129. sentry_sdk/opentelemetry/consts.py +11 -4
  130. sentry_sdk/opentelemetry/contextvars_context.py +17 -15
  131. sentry_sdk/opentelemetry/propagator.py +38 -21
  132. sentry_sdk/opentelemetry/sampler.py +51 -34
  133. sentry_sdk/opentelemetry/scope.py +36 -37
  134. sentry_sdk/opentelemetry/span_processor.py +43 -59
  135. sentry_sdk/opentelemetry/tracing.py +32 -12
  136. sentry_sdk/opentelemetry/utils.py +180 -196
  137. sentry_sdk/profiler/continuous_profiler.py +108 -97
  138. sentry_sdk/profiler/transaction_profiler.py +70 -97
  139. sentry_sdk/profiler/utils.py +11 -15
  140. sentry_sdk/scope.py +251 -264
  141. sentry_sdk/scrubber.py +22 -26
  142. sentry_sdk/serializer.py +40 -54
  143. sentry_sdk/session.py +44 -61
  144. sentry_sdk/sessions.py +35 -49
  145. sentry_sdk/spotlight.py +15 -21
  146. sentry_sdk/tracing.py +116 -182
  147. sentry_sdk/tracing_utils.py +100 -120
  148. sentry_sdk/transport.py +131 -157
  149. sentry_sdk/utils.py +232 -309
  150. sentry_sdk/worker.py +16 -28
  151. {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a3.dist-info}/METADATA +1 -1
  152. sentry_sdk-3.0.0a3.dist-info/RECORD +168 -0
  153. sentry_sdk-3.0.0a2.dist-info/RECORD +0 -154
  154. {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a3.dist-info}/WHEEL +0 -0
  155. {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a3.dist-info}/entry_points.txt +0 -0
  156. {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a3.dist-info}/licenses/LICENSE +0 -0
  157. {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a3.dist-info}/top_level.txt +0 -0
sentry_sdk/api.py CHANGED
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import inspect
2
3
  from contextlib import contextmanager
3
4
 
@@ -20,21 +21,23 @@ from sentry_sdk.opentelemetry.scope import (
20
21
  from typing import TYPE_CHECKING
21
22
 
22
23
  if TYPE_CHECKING:
23
- from collections.abc import Mapping
24
-
25
- from typing import Any
26
- from typing import Dict
27
- from typing import Optional
28
- from typing import Callable
29
- from typing import TypeVar
30
- from typing import Union
31
- from typing import Generator
32
-
33
- import sentry_sdk
24
+ from typing import Any, Optional, Callable, TypeVar, Union, Generator
34
25
 
35
26
  T = TypeVar("T")
36
27
  F = TypeVar("F", bound=Callable[..., Any])
37
28
 
29
+ from collections.abc import Mapping
30
+ from sentry_sdk.client import BaseClient
31
+ from sentry_sdk.tracing import Span
32
+ from sentry_sdk._types import (
33
+ Event,
34
+ Hint,
35
+ LogLevelStr,
36
+ ExcInfo,
37
+ BreadcrumbHint,
38
+ Breadcrumb,
39
+ )
40
+
38
41
 
39
42
  # When changing this, update __all__ in __init__.py too
40
43
  __all__ = [
@@ -69,11 +72,12 @@ __all__ = [
69
72
  "monitor",
70
73
  "use_scope",
71
74
  "use_isolation_scope",
75
+ "start_session",
76
+ "end_session",
72
77
  ]
73
78
 
74
79
 
75
- def scopemethod(f):
76
- # type: (F) -> F
80
+ def scopemethod(f: F) -> F:
77
81
  f.__doc__ = "%s\n\n%s" % (
78
82
  "Alias for :py:meth:`sentry_sdk.Scope.%s`" % f.__name__,
79
83
  inspect.getdoc(getattr(Scope, f.__name__)),
@@ -81,8 +85,7 @@ def scopemethod(f):
81
85
  return f
82
86
 
83
87
 
84
- def clientmethod(f):
85
- # type: (F) -> F
88
+ def clientmethod(f: F) -> F:
86
89
  f.__doc__ = "%s\n\n%s" % (
87
90
  "Alias for :py:meth:`sentry_sdk.Client.%s`" % f.__name__,
88
91
  inspect.getdoc(getattr(Client, f.__name__)),
@@ -91,13 +94,11 @@ def clientmethod(f):
91
94
 
92
95
 
93
96
  @scopemethod
94
- def get_client():
95
- # type: () -> sentry_sdk.client.BaseClient
97
+ def get_client() -> BaseClient:
96
98
  return Scope.get_client()
97
99
 
98
100
 
99
- def is_initialized():
100
- # type: () -> bool
101
+ def is_initialized() -> bool:
101
102
  """
102
103
  .. versionadded:: 2.0.0
103
104
 
@@ -111,26 +112,22 @@ def is_initialized():
111
112
 
112
113
 
113
114
  @scopemethod
114
- def get_global_scope():
115
- # type: () -> BaseScope
115
+ def get_global_scope() -> BaseScope:
116
116
  return Scope.get_global_scope()
117
117
 
118
118
 
119
119
  @scopemethod
120
- def get_isolation_scope():
121
- # type: () -> Scope
120
+ def get_isolation_scope() -> Scope:
122
121
  return Scope.get_isolation_scope()
123
122
 
124
123
 
125
124
  @scopemethod
126
- def get_current_scope():
127
- # type: () -> Scope
125
+ def get_current_scope() -> Scope:
128
126
  return Scope.get_current_scope()
129
127
 
130
128
 
131
129
  @scopemethod
132
- def last_event_id():
133
- # type: () -> Optional[str]
130
+ def last_event_id() -> Optional[str]:
134
131
  """
135
132
  See :py:meth:`sentry_sdk.Scope.last_event_id` documentation regarding
136
133
  this method's limitations.
@@ -140,23 +137,21 @@ def last_event_id():
140
137
 
141
138
  @scopemethod
142
139
  def capture_event(
143
- event, # type: sentry_sdk._types.Event
144
- hint=None, # type: Optional[sentry_sdk._types.Hint]
145
- scope=None, # type: Optional[Any]
146
- **scope_kwargs, # type: Any
147
- ):
148
- # type: (...) -> Optional[str]
140
+ event: Event,
141
+ hint: Optional[Hint] = None,
142
+ scope: Optional[Any] = None,
143
+ **scope_kwargs: Any,
144
+ ) -> Optional[str]:
149
145
  return get_current_scope().capture_event(event, hint, scope=scope, **scope_kwargs)
150
146
 
151
147
 
152
148
  @scopemethod
153
149
  def capture_message(
154
- message, # type: str
155
- level=None, # type: Optional[sentry_sdk._types.LogLevelStr]
156
- scope=None, # type: Optional[Any]
157
- **scope_kwargs, # type: Any
158
- ):
159
- # type: (...) -> Optional[str]
150
+ message: str,
151
+ level: Optional[LogLevelStr] = None,
152
+ scope: Optional[Any] = None,
153
+ **scope_kwargs: Any,
154
+ ) -> Optional[str]:
160
155
  return get_current_scope().capture_message(
161
156
  message, level, scope=scope, **scope_kwargs
162
157
  )
@@ -164,23 +159,21 @@ def capture_message(
164
159
 
165
160
  @scopemethod
166
161
  def capture_exception(
167
- error=None, # type: Optional[Union[BaseException, sentry_sdk._types.ExcInfo]]
168
- scope=None, # type: Optional[Any]
169
- **scope_kwargs, # type: Any
170
- ):
171
- # type: (...) -> Optional[str]
162
+ error: Optional[Union[BaseException, ExcInfo]] = None,
163
+ scope: Optional[Any] = None,
164
+ **scope_kwargs: Any,
165
+ ) -> Optional[str]:
172
166
  return get_current_scope().capture_exception(error, scope=scope, **scope_kwargs)
173
167
 
174
168
 
175
169
  @scopemethod
176
170
  def add_attachment(
177
- bytes=None, # type: Union[None, bytes, Callable[[], bytes]]
178
- filename=None, # type: Optional[str]
179
- path=None, # type: Optional[str]
180
- content_type=None, # type: Optional[str]
181
- add_to_transactions=False, # type: bool
182
- ):
183
- # type: (...) -> None
171
+ bytes: Union[None, bytes, Callable[[], bytes]] = None,
172
+ filename: Optional[str] = None,
173
+ path: Optional[str] = None,
174
+ content_type: Optional[str] = None,
175
+ add_to_transactions: bool = False,
176
+ ) -> None:
184
177
  return get_isolation_scope().add_attachment(
185
178
  bytes, filename, path, content_type, add_to_transactions
186
179
  )
@@ -188,61 +181,52 @@ def add_attachment(
188
181
 
189
182
  @scopemethod
190
183
  def add_breadcrumb(
191
- crumb=None, # type: Optional[sentry_sdk._types.Breadcrumb]
192
- hint=None, # type: Optional[sentry_sdk._types.BreadcrumbHint]
193
- **kwargs, # type: Any
194
- ):
195
- # type: (...) -> None
184
+ crumb: Optional[Breadcrumb] = None,
185
+ hint: Optional[BreadcrumbHint] = None,
186
+ **kwargs: Any,
187
+ ) -> None:
196
188
  return get_isolation_scope().add_breadcrumb(crumb, hint, **kwargs)
197
189
 
198
190
 
199
191
  @scopemethod
200
- def set_tag(key, value):
201
- # type: (str, Any) -> None
192
+ def set_tag(key: str, value: Any) -> None:
202
193
  return get_isolation_scope().set_tag(key, value)
203
194
 
204
195
 
205
196
  @scopemethod
206
- def set_tags(tags):
207
- # type: (Mapping[str, object]) -> None
197
+ def set_tags(tags: Mapping[str, object]) -> None:
208
198
  return get_isolation_scope().set_tags(tags)
209
199
 
210
200
 
211
201
  @scopemethod
212
- def set_context(key, value):
213
- # type: (str, Dict[str, Any]) -> None
202
+ def set_context(key: str, value: dict[str, Any]) -> None:
214
203
  return get_isolation_scope().set_context(key, value)
215
204
 
216
205
 
217
206
  @scopemethod
218
- def set_extra(key, value):
219
- # type: (str, Any) -> None
207
+ def set_extra(key: str, value: Any) -> None:
220
208
  return get_isolation_scope().set_extra(key, value)
221
209
 
222
210
 
223
211
  @scopemethod
224
- def set_user(value):
225
- # type: (Optional[Dict[str, Any]]) -> None
212
+ def set_user(value: Optional[dict[str, Any]]) -> None:
226
213
  return get_isolation_scope().set_user(value)
227
214
 
228
215
 
229
216
  @scopemethod
230
- def set_level(value):
231
- # type: (sentry_sdk._types.LogLevelStr) -> None
217
+ def set_level(value: LogLevelStr) -> None:
232
218
  return get_isolation_scope().set_level(value)
233
219
 
234
220
 
235
221
  @clientmethod
236
222
  def flush(
237
- timeout=None, # type: Optional[float]
238
- callback=None, # type: Optional[Callable[[int, float], None]]
239
- ):
240
- # type: (...) -> None
223
+ timeout: Optional[float] = None,
224
+ callback: Optional[Callable[[int, float], None]] = None,
225
+ ) -> None:
241
226
  return get_client().flush(timeout=timeout, callback=callback)
242
227
 
243
228
 
244
- def start_span(**kwargs):
245
- # type: (Any) -> sentry_sdk.tracing.Span
229
+ def start_span(**kwargs: Any) -> Span:
246
230
  """
247
231
  Start and return a span.
248
232
 
@@ -258,11 +242,7 @@ def start_span(**kwargs):
258
242
  return get_current_scope().start_span(**kwargs)
259
243
 
260
244
 
261
- def start_transaction(
262
- transaction=None, # type: Optional[sentry_sdk.tracing.Span]
263
- **kwargs, # type: Any
264
- ):
265
- # type: (...) -> sentry_sdk.tracing.Span
245
+ def start_transaction(transaction: Optional[Span] = None, **kwargs: Any) -> Span:
266
246
  """
267
247
  .. deprecated:: 3.0.0
268
248
  This function is deprecated and will be removed in a future release.
@@ -301,24 +281,21 @@ def start_transaction(
301
281
  )
302
282
 
303
283
 
304
- def get_current_span(scope=None):
305
- # type: (Optional[Scope]) -> Optional[sentry_sdk.tracing.Span]
284
+ def get_current_span(scope: Optional[Scope] = None) -> Optional[Span]:
306
285
  """
307
286
  Returns the currently active span if there is one running, otherwise `None`
308
287
  """
309
288
  return tracing_utils.get_current_span(scope)
310
289
 
311
290
 
312
- def get_traceparent():
313
- # type: () -> Optional[str]
291
+ def get_traceparent() -> Optional[str]:
314
292
  """
315
293
  Returns the traceparent either from the active span or from the scope.
316
294
  """
317
295
  return get_current_scope().get_traceparent()
318
296
 
319
297
 
320
- def get_baggage():
321
- # type: () -> Optional[str]
298
+ def get_baggage() -> Optional[str]:
322
299
  """
323
300
  Returns Baggage either from the active span or from the scope.
324
301
  """
@@ -330,10 +307,21 @@ def get_baggage():
330
307
 
331
308
 
332
309
  @contextmanager
333
- def continue_trace(environ_or_headers):
334
- # type: (Dict[str, Any]) -> Generator[None, None, None]
310
+ def continue_trace(environ_or_headers: dict[str, Any]) -> Generator[None, None, None]:
335
311
  """
336
312
  Sets the propagation context from environment or headers to continue an incoming trace.
337
313
  """
338
314
  with get_isolation_scope().continue_trace(environ_or_headers):
339
315
  yield
316
+
317
+
318
+ @scopemethod
319
+ def start_session(
320
+ session_mode: str = "application",
321
+ ) -> None:
322
+ return get_isolation_scope().start_session(session_mode=session_mode)
323
+
324
+
325
+ @scopemethod
326
+ def end_session() -> None:
327
+ return get_isolation_scope().end_session()
sentry_sdk/attachments.py CHANGED
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import os
2
3
  import mimetypes
3
4
 
@@ -31,13 +32,12 @@ class Attachment:
31
32
 
32
33
  def __init__(
33
34
  self,
34
- bytes=None, # type: Union[None, bytes, Callable[[], bytes]]
35
- filename=None, # type: Optional[str]
36
- path=None, # type: Optional[str]
37
- content_type=None, # type: Optional[str]
38
- add_to_transactions=False, # type: bool
39
- ):
40
- # type: (...) -> None
35
+ bytes: Union[None, bytes, Callable[[], bytes]] = None,
36
+ filename: Optional[str] = None,
37
+ path: Optional[str] = None,
38
+ content_type: Optional[str] = None,
39
+ add_to_transactions: bool = False,
40
+ ) -> None:
41
41
  if bytes is None and path is None:
42
42
  raise TypeError("path or raw bytes required for attachment")
43
43
  if filename is None and path is not None:
@@ -52,10 +52,9 @@ class Attachment:
52
52
  self.content_type = content_type
53
53
  self.add_to_transactions = add_to_transactions
54
54
 
55
- def to_envelope_item(self):
56
- # type: () -> Item
55
+ def to_envelope_item(self) -> Item:
57
56
  """Returns an envelope item for this attachment."""
58
- payload = None # type: Union[None, PayloadRef, bytes]
57
+ payload: Union[None, PayloadRef, bytes] = None
59
58
  if self.bytes is not None:
60
59
  if callable(self.bytes):
61
60
  payload = self.bytes()
@@ -70,6 +69,5 @@ class Attachment:
70
69
  filename=self.filename,
71
70
  )
72
71
 
73
- def __repr__(self):
74
- # type: () -> str
72
+ def __repr__(self) -> str:
75
73
  return "<Attachment %r>" % (self.filename,)