Skip to content

Commit de89a71

Browse files
committed
Merge branch 'potel-base' into potel-base-run-all-tests
2 parents fdb2cfa + 9d8c0b7 commit de89a71

File tree

15 files changed

+367
-38
lines changed

15 files changed

+367
-38
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# Changelog
22

3+
## 2.19.1
4+
5+
### Various fixes & improvements
6+
7+
- Fix errors when instrumenting Django cache (#3855) by @BYK
8+
- Copy `scope.client` reference as well (#3857) by @sl0thentr0py
9+
- Don't give up on Spotlight on 3 errors (#3856) by @BYK
10+
- Add missing stack frames (#3673) by @antonpirker
11+
- Fix wrong metadata type in async gRPC interceptor (#3205) by @fdellekart
12+
- Rename launch darkly hook to match JS SDK (#3743) by @aliu39
13+
- Script for checking if our instrumented libs are Python 3.13 compatible (#3425) by @antonpirker
14+
- Improve Ray tests (#3846) by @antonpirker
15+
- Test with Celery `5.5.0rc3` (#3842) by @sentrivana
16+
- Fix asyncio testing setup (#3832) by @sl0thentr0py
17+
- Bump `codecov/codecov-action` from `5.0.2` to `5.0.7` (#3821) by @dependabot
18+
- Fix CI (#3834) by @sentrivana
19+
- Use new ClickHouse GH action (#3826) by @antonpirker
20+
321
## 2.19.0
422

523
### Various fixes & improvements

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
copyright = "2019-{}, Sentry Team and Contributors".format(datetime.now().year)
3232
author = "Sentry Team and Contributors"
3333

34-
release = "2.19.0"
34+
release = "2.19.1"
3535
version = ".".join(release.split(".")[:2]) # The short X.Y version.
3636

3737

scripts/ready_yet/main.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import time
2+
import re
3+
import sys
4+
5+
import requests
6+
7+
from collections import defaultdict
8+
9+
from pathlib import Path
10+
11+
from tox.config.cli.parse import get_options
12+
from tox.session.state import State
13+
from tox.config.sets import CoreConfigSet
14+
from tox.config.source.tox_ini import ToxIni
15+
16+
PYTHON_VERSION = "3.13"
17+
18+
MATCH_LIB_SENTRY_REGEX = r"py[\d\.]*-(.*)-.*"
19+
20+
PYPI_PROJECT_URL = "https://pypi.python.org/pypi/{project}/json"
21+
PYPI_VERSION_URL = "https://pypi.python.org/pypi/{project}/{version}/json"
22+
23+
24+
def get_tox_envs(tox_ini_path: Path) -> list:
25+
tox_ini = ToxIni(tox_ini_path)
26+
conf = State(get_options(), []).conf
27+
tox_section = next(tox_ini.sections())
28+
core_config_set = CoreConfigSet(
29+
conf, tox_section, tox_ini_path.parent, tox_ini_path
30+
)
31+
(
32+
core_config_set.loaders.extend(
33+
tox_ini.get_loaders(
34+
tox_section,
35+
base=[],
36+
override_map=defaultdict(list, {}),
37+
conf=core_config_set,
38+
)
39+
)
40+
)
41+
return core_config_set.load("env_list")
42+
43+
44+
def get_libs(tox_ini: Path, regex: str) -> set:
45+
libs = set()
46+
for env in get_tox_envs(tox_ini):
47+
match = re.match(regex, env)
48+
if match:
49+
libs.add(match.group(1))
50+
51+
return sorted(libs)
52+
53+
54+
def main():
55+
"""
56+
Check if libraries in our tox.ini are ready for Python version defined in `PYTHON_VERSION`.
57+
"""
58+
print(f"Checking libs from tox.ini for Python {PYTHON_VERSION} compatibility:")
59+
60+
ready = set()
61+
not_ready = set()
62+
not_found = set()
63+
64+
tox_ini = Path(__file__).parent.parent.parent.joinpath("tox.ini")
65+
66+
libs = get_libs(tox_ini, MATCH_LIB_SENTRY_REGEX)
67+
68+
for lib in libs:
69+
print(".", end="")
70+
sys.stdout.flush()
71+
72+
# Get latest version of lib
73+
url = PYPI_PROJECT_URL.format(project=lib)
74+
pypi_data = requests.get(url)
75+
76+
if pypi_data.status_code != 200:
77+
not_found.add(lib)
78+
continue
79+
80+
latest_version = pypi_data.json()["info"]["version"]
81+
82+
# Get supported Python version of latest version of lib
83+
url = PYPI_PROJECT_URL.format(project=lib, version=latest_version)
84+
pypi_data = requests.get(url)
85+
86+
if pypi_data.status_code != 200:
87+
continue
88+
89+
classifiers = pypi_data.json()["info"]["classifiers"]
90+
91+
if f"Programming Language :: Python :: {PYTHON_VERSION}" in classifiers:
92+
ready.add(lib)
93+
else:
94+
not_ready.add(lib)
95+
96+
# cut pypi some slack
97+
time.sleep(0.1)
98+
99+
# Print report
100+
print("\n")
101+
print(f"\nReady for Python {PYTHON_VERSION}:")
102+
if len(ready) == 0:
103+
print("- None ")
104+
105+
for x in sorted(ready):
106+
print(f"- {x}")
107+
108+
print(f"\nNOT ready for Python {PYTHON_VERSION}:")
109+
if len(not_ready) == 0:
110+
print("- None ")
111+
112+
for x in sorted(not_ready):
113+
print(f"- {x}")
114+
115+
print("\nNot found on PyPI:")
116+
if len(not_found) == 0:
117+
print("- None ")
118+
119+
for x in sorted(not_found):
120+
print(f"- {x}")
121+
122+
123+
if __name__ == "__main__":
124+
main()

scripts/ready_yet/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
requests
2+
pathlib
3+
tox

scripts/ready_yet/run.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env bash
2+
3+
# exit on first error
4+
set -xe
5+
6+
reset
7+
8+
# create and activate virtual environment
9+
python -m venv .venv
10+
source .venv/bin/activate
11+
12+
# Install (or update) requirements
13+
python -m pip install -r requirements.txt
14+
15+
# Run the script
16+
python main.py

sentry_sdk/consts.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
# up top to prevent circular import due to integration import
77
DEFAULT_MAX_VALUE_LENGTH = 1024
88

9+
DEFAULT_MAX_STACK_FRAMES = 100
10+
DEFAULT_ADD_FULL_STACK = False
11+
912

1013
# Also needs to be at the top to prevent circular import
1114
class EndpointType(Enum):
@@ -537,6 +540,8 @@ def __init__(
537540
cert_file=None, # type: Optional[str]
538541
key_file=None, # type: Optional[str]
539542
custom_repr=None, # type: Optional[Callable[..., Optional[str]]]
543+
add_full_stack=DEFAULT_ADD_FULL_STACK, # type: bool
544+
max_stack_frames=DEFAULT_MAX_STACK_FRAMES, # type: Optional[int]
540545
):
541546
# type: (...) -> None
542547
pass
@@ -562,4 +567,4 @@ def _get_default_options():
562567
del _get_default_options
563568

564569

565-
VERSION = "2.19.0"
570+
VERSION = "2.19.1"

sentry_sdk/integrations/django/caching.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,12 @@ def _instrument_call(
7676
span.set_data(SPANDATA.CACHE_HIT, True)
7777
else:
7878
span.set_data(SPANDATA.CACHE_HIT, False)
79-
else:
80-
try:
79+
else: # TODO: We don't handle `get_or_set` which we should
80+
arg_count = len(args)
81+
if arg_count >= 2:
8182
# 'set' command
8283
item_size = len(str(args[1]))
83-
except IndexError:
84+
elif arg_count == 1:
8485
# 'set_many' command
8586
item_size = len(str(args[0]))
8687

sentry_sdk/integrations/grpc/aio/client.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
ClientCallDetails,
77
UnaryUnaryCall,
88
UnaryStreamCall,
9+
Metadata,
910
)
1011
from google.protobuf.message import Message
1112

@@ -19,23 +20,19 @@ class ClientInterceptor:
1920
def _update_client_call_details_metadata_from_scope(
2021
client_call_details: ClientCallDetails,
2122
) -> ClientCallDetails:
22-
metadata = (
23-
list(client_call_details.metadata) if client_call_details.metadata else []
24-
)
23+
if client_call_details.metadata is None:
24+
client_call_details = client_call_details._replace(metadata=Metadata())
25+
elif not isinstance(client_call_details.metadata, Metadata):
26+
# This is a workaround for a GRPC bug, which was fixed in grpcio v1.60.0
27+
# See https://github.com/grpc/grpc/issues/34298.
28+
client_call_details = client_call_details._replace(
29+
metadata=Metadata.from_tuple(client_call_details.metadata)
30+
)
2531
for (
2632
key,
2733
value,
2834
) in sentry_sdk.get_current_scope().iter_trace_propagation_headers():
29-
metadata.append((key, value))
30-
31-
client_call_details = ClientCallDetails(
32-
method=client_call_details.method,
33-
timeout=client_call_details.timeout,
34-
metadata=metadata,
35-
credentials=client_call_details.credentials,
36-
wait_for_ready=client_call_details.wait_for_ready,
37-
)
38-
35+
client_call_details.metadata.add(key, value)
3936
return client_call_details
4037

4138

sentry_sdk/scope.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ def __copy__(self):
203203
rv = object.__new__(self.__class__) # type: Scope
204204

205205
rv._type = self._type
206+
rv.client = self.client
206207
rv._level = self._level
207208
rv._name = self._name
208209
rv._fingerprint = self._fingerprint

sentry_sdk/spotlight.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,6 @@ def __init__(self, url):
4242

4343
def capture_envelope(self, envelope):
4444
# type: (Envelope) -> None
45-
if self.tries > 3:
46-
sentry_logger.warning(
47-
"Too many errors sending to Spotlight, stop sending events there."
48-
)
49-
return
5045
body = io.BytesIO()
5146
envelope.serialize_into(body)
5247
try:
@@ -60,7 +55,7 @@ def capture_envelope(self, envelope):
6055
)
6156
req.close()
6257
except Exception as e:
63-
self.tries += 1
58+
# TODO: Implement buffering and retrying with exponential backoff
6459
sentry_logger.warning(str(e))
6560

6661

0 commit comments

Comments
 (0)