Skip to content

Commit ec0fd75

Browse files
committed
Update trace decorator to not use start_child
1 parent a012fe4 commit ec0fd75

File tree

4 files changed

+66
-73
lines changed

4 files changed

+66
-73
lines changed

sentry_sdk/tracing_utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -729,9 +729,10 @@ async def func_with_tracing(*args, **kwargs):
729729
)
730730
return await func(*args, **kwargs)
731731

732-
with span.start_child(
732+
with sentry_sdk.start_span(
733733
op=OP.FUNCTION,
734734
name=qualname_from_function(func),
735+
only_if_parent=True,
735736
):
736737
return await func(*args, **kwargs)
737738

@@ -757,9 +758,10 @@ def func_with_tracing(*args, **kwargs):
757758
)
758759
return func(*args, **kwargs)
759760

760-
with span.start_child(
761+
with sentry_sdk.start_span(
761762
op=OP.FUNCTION,
762763
name=qualname_from_function(func),
764+
only_if_parent=True,
763765
):
764766
return func(*args, **kwargs)
765767

tests/conftest.py

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
import socket
44
import warnings
55
from threading import Thread
6-
from contextlib import contextmanager
76
from http.server import BaseHTTPRequestHandler, HTTPServer
8-
from unittest import mock
97

108
import pytest
119
import jsonschema
@@ -35,12 +33,6 @@
3533

3634
from tests import _warning_recorder, _warning_recorder_mgr
3735

38-
from typing import TYPE_CHECKING
39-
40-
if TYPE_CHECKING:
41-
from typing import Optional
42-
from collections.abc import Iterator
43-
4436

4537
SENTRY_EVENT_SCHEMA = "./checkouts/data-schemas/relay/event.schema.json"
4638

@@ -637,23 +629,6 @@ def werkzeug_set_cookie(client, servername, key, value):
637629
client.set_cookie(key, value)
638630

639631

640-
@contextmanager
641-
def patch_start_tracing_child(fake_transaction_is_none=False):
642-
# type: (bool) -> Iterator[Optional[mock.MagicMock]]
643-
if not fake_transaction_is_none:
644-
fake_transaction = mock.MagicMock()
645-
fake_start_child = mock.MagicMock()
646-
fake_transaction.start_child = fake_start_child
647-
else:
648-
fake_transaction = None
649-
fake_start_child = None
650-
651-
with mock.patch(
652-
"sentry_sdk.tracing_utils.get_current_span", return_value=fake_transaction
653-
):
654-
yield fake_start_child
655-
656-
657632
class ApproxDict(dict):
658633
def __eq__(self, other):
659634
# For an ApproxDict to equal another dict, the other dict just needs to contain

tests/test_basics.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,8 @@ def _hello_world(word):
748748

749749

750750
def test_functions_to_trace(sentry_init, capture_events):
751+
original_sleep = time.sleep
752+
751753
functions_to_trace = [
752754
{"qualified_name": "tests.test_basics._hello_world"},
753755
{"qualified_name": "time.sleep"},
@@ -775,6 +777,8 @@ def test_functions_to_trace(sentry_init, capture_events):
775777
assert event["spans"][1]["description"] == "tests.test_basics._hello_world"
776778
assert event["spans"][2]["description"] == "tests.test_basics._hello_world"
777779

780+
time.sleep = original_sleep
781+
778782

779783
class WorldGreeter:
780784
def __init__(self, word):

tests/tracing/test_decorator.py

Lines changed: 58 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
import pytest
55

6+
import sentry_sdk
67
from sentry_sdk.tracing import trace
78
from sentry_sdk.tracing_utils import start_child_span_decorator
89
from sentry_sdk.utils import logger
9-
from tests.conftest import patch_start_tracing_child
1010

1111

1212
def my_example_function():
@@ -17,68 +17,80 @@ async def my_async_example_function():
1717
return "return_of_async_function"
1818

1919

20-
@pytest.mark.forked
21-
def test_trace_decorator():
22-
with patch_start_tracing_child() as fake_start_child:
20+
def test_trace_decorator(sentry_init, capture_events):
21+
sentry_init(traces_sample_rate=1.0)
22+
events = capture_events()
23+
24+
with sentry_sdk.start_span(name="test"):
2325
result = my_example_function()
24-
fake_start_child.assert_not_called()
2526
assert result == "return_of_sync_function"
2627

27-
result2 = start_child_span_decorator(my_example_function)()
28-
fake_start_child.assert_called_once_with(
29-
op="function", name="test_decorator.my_example_function"
30-
)
28+
result2 = trace(my_example_function)()
3129
assert result2 == "return_of_sync_function"
3230

31+
(event,) = events
32+
(span,) = event["spans"]
33+
assert span["op"] == "function"
34+
assert span["description"] == "test_decorator.my_example_function"
3335

34-
@pytest.mark.forked
35-
def test_trace_decorator_no_trx():
36-
with patch_start_tracing_child(fake_transaction_is_none=True):
37-
with mock.patch.object(logger, "debug", mock.Mock()) as fake_debug:
38-
result = my_example_function()
39-
fake_debug.assert_not_called()
40-
assert result == "return_of_sync_function"
4136

42-
result2 = start_child_span_decorator(my_example_function)()
43-
fake_debug.assert_called_once_with(
44-
"Cannot create a child span for %s. "
45-
"Please start a Sentry transaction before calling this function.",
46-
"test_decorator.my_example_function",
47-
)
48-
assert result2 == "return_of_sync_function"
37+
def test_trace_decorator_no_trx(sentry_init, capture_events):
38+
sentry_init(traces_sample_rate=1.0)
39+
events = capture_events()
40+
41+
with mock.patch.object(logger, "debug", mock.Mock()) as fake_debug:
42+
result = my_example_function()
43+
assert result == "return_of_sync_function"
44+
fake_debug.assert_not_called()
45+
46+
result2 = trace(my_example_function)()
47+
assert result2 == "return_of_sync_function"
48+
fake_debug.assert_called_once_with(
49+
"Cannot create a child span for %s. "
50+
"Please start a Sentry transaction before calling this function.",
51+
"test_decorator.my_example_function",
52+
)
53+
54+
assert len(events) == 0
4955

5056

51-
@pytest.mark.forked
5257
@pytest.mark.asyncio
53-
async def test_trace_decorator_async():
54-
with patch_start_tracing_child() as fake_start_child:
58+
async def test_trace_decorator_async(sentry_init, capture_events):
59+
sentry_init(traces_sample_rate=1.0)
60+
events = capture_events()
61+
62+
with sentry_sdk.start_span(name="test"):
5563
result = await my_async_example_function()
56-
fake_start_child.assert_not_called()
5764
assert result == "return_of_async_function"
5865

59-
result2 = await start_child_span_decorator(my_async_example_function)()
60-
fake_start_child.assert_called_once_with(
61-
op="function",
62-
name="test_decorator.my_async_example_function",
63-
)
66+
result2 = await trace(my_async_example_function)()
6467
assert result2 == "return_of_async_function"
6568

69+
(event,) = events
70+
(span,) = event["spans"]
71+
assert span["op"] == "function"
72+
assert span["description"] == "test_decorator.my_async_example_function"
73+
6674

6775
@pytest.mark.asyncio
68-
async def test_trace_decorator_async_no_trx():
69-
with patch_start_tracing_child(fake_transaction_is_none=True):
70-
with mock.patch.object(logger, "debug", mock.Mock()) as fake_debug:
71-
result = await my_async_example_function()
72-
fake_debug.assert_not_called()
73-
assert result == "return_of_async_function"
74-
75-
result2 = await start_child_span_decorator(my_async_example_function)()
76-
fake_debug.assert_called_once_with(
77-
"Cannot create a child span for %s. "
78-
"Please start a Sentry transaction before calling this function.",
79-
"test_decorator.my_async_example_function",
80-
)
81-
assert result2 == "return_of_async_function"
76+
async def test_trace_decorator_async_no_trx(sentry_init, capture_events):
77+
sentry_init(traces_sample_rate=1.0)
78+
events = capture_events()
79+
80+
with mock.patch.object(logger, "debug", mock.Mock()) as fake_debug:
81+
result = await my_async_example_function()
82+
fake_debug.assert_not_called()
83+
assert result == "return_of_async_function"
84+
85+
result2 = await start_child_span_decorator(my_async_example_function)()
86+
fake_debug.assert_called_once_with(
87+
"Cannot create a child span for %s. "
88+
"Please start a Sentry transaction before calling this function.",
89+
"test_decorator.my_async_example_function",
90+
)
91+
assert result2 == "return_of_async_function"
92+
93+
assert len(events) == 0
8294

8395

8496
def test_functions_to_trace_signature_unchanged_sync(sentry_init):

0 commit comments

Comments
 (0)