sentry-sdk 2.35.1__py2.py3-none-any.whl → 2.36.0__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.

@@ -10,7 +10,9 @@ from sentry_sdk.utils import ContextVar
10
10
  from typing import TYPE_CHECKING
11
11
 
12
12
  if TYPE_CHECKING:
13
- from typing import Optional, Callable, Any
13
+ from typing import Optional, Callable, Awaitable, Any, Union, TypeVar
14
+
15
+ F = TypeVar("F", bound=Union[Callable[..., Any], Callable[..., Awaitable[Any]]])
14
16
 
15
17
  _ai_pipeline_name = ContextVar("ai_pipeline_name", default=None)
16
18
 
@@ -26,9 +28,9 @@ def get_ai_pipeline_name():
26
28
 
27
29
 
28
30
  def ai_track(description, **span_kwargs):
29
- # type: (str, Any) -> Callable[..., Any]
31
+ # type: (str, Any) -> Callable[[F], F]
30
32
  def decorator(f):
31
- # type: (Callable[..., Any]) -> Callable[..., Any]
33
+ # type: (F) -> F
32
34
  def sync_wrapped(*args, **kwargs):
33
35
  # type: (Any, Any) -> Any
34
36
  curr_pipeline = _ai_pipeline_name.get()
@@ -88,9 +90,9 @@ def ai_track(description, **span_kwargs):
88
90
  return res
89
91
 
90
92
  if inspect.iscoroutinefunction(f):
91
- return wraps(f)(async_wrapped)
93
+ return wraps(f)(async_wrapped) # type: ignore
92
94
  else:
93
- return wraps(f)(sync_wrapped)
95
+ return wraps(f)(sync_wrapped) # type: ignore
94
96
 
95
97
  return decorator
96
98
 
sentry_sdk/consts.py CHANGED
@@ -1329,4 +1329,4 @@ DEFAULT_OPTIONS = _get_default_options()
1329
1329
  del _get_default_options
1330
1330
 
1331
1331
 
1332
- VERSION = "2.35.1"
1332
+ VERSION = "2.36.0"
@@ -141,7 +141,7 @@ _MIN_VERSIONS = {
141
141
  "graphene": (3, 3),
142
142
  "grpc": (1, 32, 0), # grpcio
143
143
  "huggingface_hub": (0, 22),
144
- "langchain": (0, 0, 210),
144
+ "langchain": (0, 1, 0),
145
145
  "launchdarkly": (9, 8, 0),
146
146
  "loguru": (0, 7, 0),
147
147
  "openai": (1, 0, 0),
@@ -356,12 +356,14 @@ class SentryLogsHandler(_BaseHandler):
356
356
  record.levelno, SEVERITY_TO_OTEL_SEVERITY
357
357
  )
358
358
  project_root = client.options["project_root"]
359
+
359
360
  attrs = self._extra_from_record(record) # type: Any
360
361
  attrs["sentry.origin"] = "auto.logger.log"
361
- if isinstance(record.msg, str):
362
- attrs["sentry.message.template"] = record.msg
362
+
363
+ parameters_set = False
363
364
  if record.args is not None:
364
365
  if isinstance(record.args, tuple):
366
+ parameters_set = bool(record.args)
365
367
  for i, arg in enumerate(record.args):
366
368
  attrs[f"sentry.message.parameter.{i}"] = (
367
369
  arg
@@ -369,19 +371,28 @@ class SentryLogsHandler(_BaseHandler):
369
371
  else safe_repr(arg)
370
372
  )
371
373
  elif isinstance(record.args, dict):
374
+ parameters_set = bool(record.args)
372
375
  for key, value in record.args.items():
373
376
  attrs[f"sentry.message.parameter.{key}"] = (
374
377
  value
375
378
  if isinstance(value, (str, float, int, bool))
376
379
  else safe_repr(value)
377
380
  )
381
+
382
+ if parameters_set and isinstance(record.msg, str):
383
+ # only include template if there is at least one
384
+ # sentry.message.parameter.X set
385
+ attrs["sentry.message.template"] = record.msg
386
+
378
387
  if record.lineno:
379
388
  attrs["code.line.number"] = record.lineno
389
+
380
390
  if record.pathname:
381
391
  if project_root is not None and record.pathname.startswith(project_root):
382
392
  attrs["code.file.path"] = record.pathname[len(project_root) + 1 :]
383
393
  else:
384
394
  attrs["code.file.path"] = record.pathname
395
+
385
396
  if record.funcName:
386
397
  attrs["code.function.name"] = record.funcName
387
398
 
@@ -78,12 +78,12 @@ class OpenAIIntegration(Integration):
78
78
  return 0
79
79
 
80
80
 
81
- def _capture_exception(exc):
82
- # type: (Any) -> None
81
+ def _capture_exception(exc, manual_span_cleanup=True):
82
+ # type: (Any, bool) -> None
83
83
  # Close an eventually open span
84
84
  # We need to do this by hand because we are not using the start_span context manager
85
85
  current_span = sentry_sdk.get_current_span()
86
- if current_span is not None:
86
+ if manual_span_cleanup and current_span is not None:
87
87
  current_span.__exit__(None, None, None)
88
88
 
89
89
  event, hint = event_from_exception(
@@ -516,7 +516,7 @@ def _wrap_embeddings_create(f):
516
516
  try:
517
517
  result = f(*args, **kwargs)
518
518
  except Exception as e:
519
- _capture_exception(e)
519
+ _capture_exception(e, manual_span_cleanup=False)
520
520
  raise e from None
521
521
 
522
522
  return gen.send(result)
@@ -550,7 +550,7 @@ def _wrap_async_embeddings_create(f):
550
550
  try:
551
551
  result = await f(*args, **kwargs)
552
552
  except Exception as e:
553
- _capture_exception(e)
553
+ _capture_exception(e, manual_span_cleanup=False)
554
554
  raise e from None
555
555
 
556
556
  return gen.send(result)
@@ -0,0 +1,53 @@
1
+ import sys
2
+
3
+ import sentry_sdk
4
+ from sentry_sdk.utils import (
5
+ capture_internal_exceptions,
6
+ event_from_exception,
7
+ )
8
+ from sentry_sdk.integrations import Integration
9
+
10
+ from typing import TYPE_CHECKING
11
+
12
+ if TYPE_CHECKING:
13
+ from typing import Callable
14
+ from typing import Any
15
+
16
+
17
+ class UnraisablehookIntegration(Integration):
18
+ identifier = "unraisablehook"
19
+
20
+ @staticmethod
21
+ def setup_once():
22
+ # type: () -> None
23
+ sys.unraisablehook = _make_unraisable(sys.unraisablehook)
24
+
25
+
26
+ def _make_unraisable(old_unraisablehook):
27
+ # type: (Callable[[sys.UnraisableHookArgs], Any]) -> Callable[[sys.UnraisableHookArgs], Any]
28
+ def sentry_sdk_unraisablehook(unraisable):
29
+ # type: (sys.UnraisableHookArgs) -> None
30
+ integration = sentry_sdk.get_client().get_integration(UnraisablehookIntegration)
31
+
32
+ # Note: If we replace this with ensure_integration_enabled then
33
+ # we break the exceptiongroup backport;
34
+ # See: https://github.com/getsentry/sentry-python/issues/3097
35
+ if integration is None:
36
+ return old_unraisablehook(unraisable)
37
+
38
+ if unraisable.exc_value and unraisable.exc_traceback:
39
+ with capture_internal_exceptions():
40
+ event, hint = event_from_exception(
41
+ (
42
+ unraisable.exc_type,
43
+ unraisable.exc_value,
44
+ unraisable.exc_traceback,
45
+ ),
46
+ client_options=sentry_sdk.get_client().options,
47
+ mechanism={"type": "unraisablehook", "handled": False},
48
+ )
49
+ sentry_sdk.capture_event(event, hint=hint)
50
+
51
+ return old_unraisablehook(unraisable)
52
+
53
+ return sentry_sdk_unraisablehook
sentry_sdk/logger.py CHANGED
@@ -22,13 +22,14 @@ def _capture_log(severity_text, severity_number, template, **kwargs):
22
22
  # type: (str, int, str, **Any) -> None
23
23
  client = get_client()
24
24
 
25
- attrs = {
26
- "sentry.message.template": template,
27
- } # type: dict[str, str | bool | float | int]
25
+ attrs = {} # type: dict[str, str | bool | float | int]
28
26
  if "attributes" in kwargs:
29
27
  attrs.update(kwargs.pop("attributes"))
30
28
  for k, v in kwargs.items():
31
29
  attrs[f"sentry.message.parameter.{k}"] = v
30
+ if kwargs:
31
+ # only attach template if there are parameters
32
+ attrs["sentry.message.template"] = template
32
33
 
33
34
  attrs = {
34
35
  k: (
@@ -45,6 +45,7 @@ from sentry_sdk.profiler.utils import (
45
45
  )
46
46
  from sentry_sdk.utils import (
47
47
  capture_internal_exception,
48
+ capture_internal_exceptions,
48
49
  get_current_thread_meta,
49
50
  is_gevent,
50
51
  is_valid_sample_rate,
@@ -369,12 +370,13 @@ class Profile:
369
370
 
370
371
  def __exit__(self, ty, value, tb):
371
372
  # type: (Optional[Any], Optional[Any], Optional[Any]) -> None
372
- self.stop()
373
+ with capture_internal_exceptions():
374
+ self.stop()
373
375
 
374
- scope, old_profile = self._context_manager_state
375
- del self._context_manager_state
376
+ scope, old_profile = self._context_manager_state
377
+ del self._context_manager_state
376
378
 
377
- scope.profile = old_profile
379
+ scope.profile = old_profile
378
380
 
379
381
  def write(self, ts, sample):
380
382
  # type: (int, ExtractedSample) -> None
sentry_sdk/tracing.py CHANGED
@@ -8,6 +8,7 @@ import sentry_sdk
8
8
  from sentry_sdk.consts import INSTRUMENTER, SPANSTATUS, SPANDATA, SPANTEMPLATE
9
9
  from sentry_sdk.profiler.continuous_profiler import get_profiler_id
10
10
  from sentry_sdk.utils import (
11
+ capture_internal_exceptions,
11
12
  get_current_thread_meta,
12
13
  is_valid_sample_rate,
13
14
  logger,
@@ -418,10 +419,11 @@ class Span:
418
419
  if value is not None and should_be_treated_as_error(ty, value):
419
420
  self.set_status(SPANSTATUS.INTERNAL_ERROR)
420
421
 
421
- scope, old_span = self._context_manager_state
422
- del self._context_manager_state
423
- self.finish(scope)
424
- scope.span = old_span
422
+ with capture_internal_exceptions():
423
+ scope, old_span = self._context_manager_state
424
+ del self._context_manager_state
425
+ self.finish(scope)
426
+ scope.span = old_span
425
427
 
426
428
  @property
427
429
  def containing_transaction(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry-sdk
3
- Version: 2.35.1
3
+ Version: 2.36.0
4
4
  Summary: Python client for Sentry (https://sentry.io)
5
5
  Home-page: https://github.com/getsentry/sentry-python
6
6
  Author: Sentry Team and Contributors
@@ -9,12 +9,12 @@ sentry_sdk/_werkzeug.py,sha256=m3GPf-jHd8v3eVOfBHaKw5f0uHoLkXrSO1EcY-8EisY,3734
9
9
  sentry_sdk/api.py,sha256=OkwQ2tA5YASJ77wLOteUdv_woPF4wL_JTOAMxe9z8k4,15282
10
10
  sentry_sdk/attachments.py,sha256=0Dylhm065O6hNFjB40fWCd5Hg4qWSXndmi1TPWglZkI,3109
11
11
  sentry_sdk/client.py,sha256=oQcolwFdLvuX4huUaCcpgABy3M5Yb4IhzymlzyrqfkE,38860
12
- sentry_sdk/consts.py,sha256=MfjbaXeUP3zZu7u--NP32syNjlppzDW5Ke7tN7D6aSI,49767
12
+ sentry_sdk/consts.py,sha256=uw1W8s4s2lY_9fXS3EqsRXwV_95ArGu7ZIQCijcnmAM,49767
13
13
  sentry_sdk/debug.py,sha256=ddBehQlAuQC1sg1XO-N4N3diZ0x0iT5RWJwFdrtcsjw,1019
14
14
  sentry_sdk/envelope.py,sha256=Mgcib0uLm_5tSVzOrznRLdK9B3CjQ6TEgM1ZIZIfjWo,10355
15
15
  sentry_sdk/feature_flags.py,sha256=99JRig6TBkrkBzVCKqYcmVgjsuA_Hk-ul7jFHGhJplc,2233
16
16
  sentry_sdk/hub.py,sha256=2QLvEtIYSYV04r8h7VBmQjookILaiBZxZBGTtQKNAWg,25675
17
- sentry_sdk/logger.py,sha256=u_8zS8gjQt7FjYqz_I91sCbdsmBe7IgRqWxMP3vrsq0,2399
17
+ sentry_sdk/logger.py,sha256=HnmkMmOf1hwvxIcPW2qOvIOSnFZ9yRNDBae_eriGsoY,2471
18
18
  sentry_sdk/metrics.py,sha256=3IvBwbHlU-C-JdwDysTeJqOoVyYXsHZ7oEkkU0qTZb4,29913
19
19
  sentry_sdk/monitor.py,sha256=52CG1m2e8okFDVoTpbqfm9zeeaLa0ciC_r9x2RiXuDg,3639
20
20
  sentry_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -24,20 +24,20 @@ sentry_sdk/serializer.py,sha256=xUw3xjSsGF0cWRHL9ofe0nmWEtZvzPOHSQ6IHvo6UAc,1323
24
24
  sentry_sdk/session.py,sha256=TqDVmRKKHUDSmZb4jQR-s8wDt7Fwb6QaG21hawUGWEs,5571
25
25
  sentry_sdk/sessions.py,sha256=UZ2jfrqhYvZzTxCDGc1MLD6P_aHLJnTFetSUROIaPaA,9154
26
26
  sentry_sdk/spotlight.py,sha256=93kdd8KxdLfcPaxFnFuqHgYAAL4FCfpK1hiiPoD7Ac4,8678
27
- sentry_sdk/tracing.py,sha256=H3tp4b5aAP69hVwwu2sQQSi97dD_Bb9mtq0DhFw37zo,51485
27
+ sentry_sdk/tracing.py,sha256=FHL6u9SHGfyFCDnSbOwZiQYStTcuf8-YvV47DO4Q9DI,51578
28
28
  sentry_sdk/tracing_utils.py,sha256=0RjENkigpVHydBIk_CqOTRZ8GJQHslgHveatvelZA1c,39040
29
29
  sentry_sdk/transport.py,sha256=A0uux7XnniDJuExLudLyyFDYnS5C6r7zozGbkveUM7E,32469
30
30
  sentry_sdk/types.py,sha256=NLbnRzww2K3_oGz2GzcC8TdX5L2DXYso1-H1uCv2Hwc,1222
31
31
  sentry_sdk/utils.py,sha256=Ys7lnnvXZMIR9dcoT30CVxpUx2NnZifSy-TUNrCtMQA,61575
32
32
  sentry_sdk/worker.py,sha256=VSMaigRMbInVyupSFpBC42bft2oIViea-0C_d9ThnIo,4464
33
33
  sentry_sdk/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- sentry_sdk/ai/monitoring.py,sha256=OqQHsi832ZTL6mf38hO_qehaqMqVAb2E6HOyyaXSOtY,4948
34
+ sentry_sdk/ai/monitoring.py,sha256=bS_KneWCAL9ehml5XiyficoPVx4DUUG6acbH3cjP3I8,5057
35
35
  sentry_sdk/ai/utils.py,sha256=11PMqGCfEzAVrI2aSx-rdCl0dNYFzUi0bio6L8iM3kU,1174
36
36
  sentry_sdk/crons/__init__.py,sha256=3Zt6g1-pZZ12uRKKsC8QLm3XgJ4K1VYxgVpNNUygOZY,221
37
37
  sentry_sdk/crons/api.py,sha256=mk-UB8Im2LU2rJFdE-TV302EaKnf8kAjwEL0bIV0Hzc,1767
38
38
  sentry_sdk/crons/consts.py,sha256=dXqJk5meBSu5rjlGpqAOlkpACnuUi7svQnAFoy1ZNUU,87
39
39
  sentry_sdk/crons/decorator.py,sha256=UrjeIqBCbvsuKrfjGkKJbbLBvjw2TQvDWcTO7WwAmrI,3913
40
- sentry_sdk/integrations/__init__.py,sha256=d0-uVMIrodezjlfK10IYZLXotZ8LtZzHSWGwysAQ4RY,10251
40
+ sentry_sdk/integrations/__init__.py,sha256=DHt4Ei3sOaEBdTjA4mEpc7pwhS8kGcQgViAZ7DcNzqU,10249
41
41
  sentry_sdk/integrations/_asgi_common.py,sha256=Ypg7IctB3iPPY60ebVlzChzgT8GeGpZ0YH8VvJNDlEY,3187
42
42
  sentry_sdk/integrations/_wsgi_common.py,sha256=A1-X7l1pZCcrbUhRHkmdKiK_EemEZjn7xToJIvlEuFM,7558
43
43
  sentry_sdk/integrations/aiohttp.py,sha256=_rfDKx1arvVQwcC20vh7HG80p8XtgzqKB3iBuPYZy8A,12895
@@ -74,10 +74,10 @@ sentry_sdk/integrations/huggingface_hub.py,sha256=ypTn17T0vufQwi7ODXONFkB8fMjUrU
74
74
  sentry_sdk/integrations/langchain.py,sha256=8ht-fXKb9muG3HEnKhuSvna2G8f2_M9BBzm1jXjnqiQ,26413
75
75
  sentry_sdk/integrations/launchdarkly.py,sha256=bvtExuj68xPXZFsQeWTDR-ZBqP087tPuVzP1bNAOZHc,1935
76
76
  sentry_sdk/integrations/litestar.py,sha256=jao0f8v5JQagkBg15dUJTdWGPxpS3LmOV301-lwGkGc,11815
77
- sentry_sdk/integrations/logging.py,sha256=3IvbPmvisv9ZM98SRRYlEH5g1nNVjOZz-204CWRcg-I,13641
77
+ sentry_sdk/integrations/logging.py,sha256=4JC2ehLqd5Tz_rad8YVb9KhZnPcDzLxLh-AjopyNVEc,13905
78
78
  sentry_sdk/integrations/loguru.py,sha256=fgivPdQn3rmsMeInUd2wbNlbXPAH9MKhjaqytRVKnsI,6215
79
79
  sentry_sdk/integrations/modules.py,sha256=vzLx3Erg77Vl4mnUvAgTg_3teAuWy7zylFpAidBI9I0,820
80
- sentry_sdk/integrations/openai.py,sha256=N3CSx8OJlcx6cK2bj8GjmtcjBsw4T3fHdqlMKAzXirc,22939
80
+ sentry_sdk/integrations/openai.py,sha256=EQFY04x2BN0RZDbLvuOcg7OJ8mO2hHyzlDFx8tN_npg,23049
81
81
  sentry_sdk/integrations/openfeature.py,sha256=-vvdrN4fK0Xhu2ip41bkPIPEqdzv8xzmLu9wRlI2xPA,1131
82
82
  sentry_sdk/integrations/pure_eval.py,sha256=OvT76XvllQ_J6ABu3jVNU6KD2QAxnXMtTZ7hqhXNhpY,4581
83
83
  sentry_sdk/integrations/pymongo.py,sha256=cPpMGEbXHlV6HTHgmIDL1F-x3w7ZMROXVb4eUhLs3bw,6380
@@ -101,6 +101,7 @@ sentry_sdk/integrations/tornado.py,sha256=Qcft8FZxdVICnaa1AhsDB262sInEQZPf-pvgI-
101
101
  sentry_sdk/integrations/trytond.py,sha256=BaLCNqQeRWDbHHDEelS5tmj-p_CrbmtGEHIn6JfzEFE,1651
102
102
  sentry_sdk/integrations/typer.py,sha256=FQrFgpR9t6yQWF-oWCI9KJLFioEnA2c_1BEtYV-mPAs,1815
103
103
  sentry_sdk/integrations/unleash.py,sha256=6JshqyuAY_kbu9Nr20tMOhtgx-ryqPHCrq_EQIzeqm4,1058
104
+ sentry_sdk/integrations/unraisablehook.py,sha256=8IW8Ia9t2hKgPLh8WS8WkmeAsyjJ6Al4qi8sM6vGrpU,1753
104
105
  sentry_sdk/integrations/wsgi.py,sha256=aW_EnDCcex41NGdrxKFZsfJxJhndsMCv0d2a5LBb7wU,10747
105
106
  sentry_sdk/integrations/celery/__init__.py,sha256=FNmrLL0Cs95kv6yUCpJGu9X8Cpw20mMYGmnkBC4IL4Y,18699
106
107
  sentry_sdk/integrations/celery/beat.py,sha256=WHEdKetrDJgtZGNp1VUMa6BG1q-MhsLZMefUmVrPu3w,8953
@@ -156,11 +157,11 @@ sentry_sdk/integrations/spark/spark_driver.py,sha256=mqGQMngDAZWM78lWK5S0FPpmjd1
156
157
  sentry_sdk/integrations/spark/spark_worker.py,sha256=FGT4yRU2X_iQCC46aasMmvJfYOKmBip8KbDF_wnhvEY,3706
157
158
  sentry_sdk/profiler/__init__.py,sha256=3PI3bHk9RSkkOXZKN84DDedk_7M65EiqqaIGo-DYs0E,1291
158
159
  sentry_sdk/profiler/continuous_profiler.py,sha256=s0DHkj3RZYRg9HnQQC0G44ku6DaFqRy30fZTMtTYvIs,22828
159
- sentry_sdk/profiler/transaction_profiler.py,sha256=4Gj6FHLnK1di3GmnI1cCc_DbNcBVMdBjZZFvPvm7C7k,27877
160
+ sentry_sdk/profiler/transaction_profiler.py,sha256=e3MsUqs-YIp6-nmzpmBYGoWWIF7RyuSGu24Dj-8GXAU,27970
160
161
  sentry_sdk/profiler/utils.py,sha256=G5s4tYai9ATJqcHrQ3bOIxlK6jIaHzELrDtU5k3N4HI,6556
161
- sentry_sdk-2.35.1.dist-info/licenses/LICENSE,sha256=KhQNZg9GKBL6KQvHQNBGMxJsXsRdhLebVp4Sew7t3Qs,1093
162
- sentry_sdk-2.35.1.dist-info/METADATA,sha256=aSyeMwy7g_kh0l6ZbIwJzcwGEKP2kxIX77QMBPMQHqQ,10278
163
- sentry_sdk-2.35.1.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
164
- sentry_sdk-2.35.1.dist-info/entry_points.txt,sha256=qacZEz40UspQZD1IukCXykx0JtImqGDOctS5KfOLTko,91
165
- sentry_sdk-2.35.1.dist-info/top_level.txt,sha256=XrQz30XE9FKXSY_yGLrd9bsv2Rk390GTDJOSujYaMxI,11
166
- sentry_sdk-2.35.1.dist-info/RECORD,,
162
+ sentry_sdk-2.36.0.dist-info/licenses/LICENSE,sha256=KhQNZg9GKBL6KQvHQNBGMxJsXsRdhLebVp4Sew7t3Qs,1093
163
+ sentry_sdk-2.36.0.dist-info/METADATA,sha256=KWUgID6zOzPsptXdO2gMhSTw0JPnGtzm4RRYNW6FXyc,10278
164
+ sentry_sdk-2.36.0.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
165
+ sentry_sdk-2.36.0.dist-info/entry_points.txt,sha256=qacZEz40UspQZD1IukCXykx0JtImqGDOctS5KfOLTko,91
166
+ sentry_sdk-2.36.0.dist-info/top_level.txt,sha256=XrQz30XE9FKXSY_yGLrd9bsv2Rk390GTDJOSujYaMxI,11
167
+ sentry_sdk-2.36.0.dist-info/RECORD,,