-
Notifications
You must be signed in to change notification settings - Fork 111
/
Copy pathtest_source_code_extraction.py
220 lines (192 loc) · 8.21 KB
/
test_source_code_extraction.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
from __future__ import annotations
import sys
from typing import Any
import pytest
from inline_snapshot import snapshot
import logfire
from logfire._internal.formatter import InspectArgumentsFailedWarning
from logfire.testing import TestExporter
def func() -> None:
with logfire.span('from function'):
pass
class AClass:
def method(self) -> None:
with logfire.span('from method'):
pass
def nested() -> None:
def bar() -> None:
class AClass:
def method(self) -> None:
with logfire.span('hi!'):
pass
AClass().method()
bar()
def normalize_filepaths(spans: list[dict[str, Any]]) -> list[dict[str, Any]]:
"""Allow these tests to run from the monorepo root directory of sdk source directory"""
for span in spans:
if 'attributes' in span: # pragma: no branch
if 'code.filepath' in span['attributes']: # pragma: no branch
span['attributes']['code.filepath'] = span['attributes']['code.filepath'].replace(
'src/packages/logfire/', ''
)
return spans
def test_source_code_extraction_function(exporter: TestExporter) -> None:
func()
assert normalize_filepaths(
exporter.exported_spans_as_dict(strip_filepaths=False, fixed_line_number=None, _strip_function_qualname=False)
) == snapshot(
[
{
'name': 'from function',
'context': {'trace_id': 1, 'span_id': 1, 'is_remote': False},
'parent': None,
'start_time': 1000000000,
'end_time': 2000000000,
'attributes': {
'code.filepath': 'tests/test_source_code_extraction.py',
'code.lineno': 15,
'code.function': 'func',
'logfire.msg_template': 'from function',
'logfire.span_type': 'span',
'logfire.msg': 'from function',
},
}
]
)
def test_source_code_extraction_method(exporter: TestExporter) -> None:
AClass().method()
code_function = 'AClass.method' if sys.version_info >= (3, 11) else 'method'
assert normalize_filepaths(
exporter.exported_spans_as_dict(strip_filepaths=False, fixed_line_number=None, _strip_function_qualname=False)
) == snapshot(
[
{
'name': 'from method',
'context': {'trace_id': 1, 'span_id': 1, 'is_remote': False},
'parent': None,
'start_time': 1000000000,
'end_time': 2000000000,
'attributes': {
'code.filepath': 'tests/test_source_code_extraction.py',
'code.lineno': 21,
'code.function': code_function,
'logfire.msg_template': 'from method',
'logfire.span_type': 'span',
'logfire.msg': 'from method',
},
}
]
)
@pytest.mark.skipif(
sys.version_info[:2] == (3, 8), reason='Warning is only raised in Python 3.9+ because f-string magic is enabled'
)
def test_source_code_extraction_module(exporter: TestExporter) -> None:
with pytest.warns(InspectArgumentsFailedWarning, match='No source code available'):
exec(
"""import logfire
with logfire.span('from module'):
pass
"""
)
assert normalize_filepaths(
exporter.exported_spans_as_dict(strip_filepaths=False, _strip_function_qualname=False)
) == snapshot(
[
{
'name': """\
Failed to introspect calling code. Please report this issue to Logfire. Falling back to normal message formatting which may result in loss of information if using an f-string. Set inspect_arguments=False in logfire.configure() to suppress this warning. The problem was:
No source code available. This happens when running in an interactive shell, using exec(), or running .pyc files without the source .py files.\
""",
'context': {'trace_id': 1, 'span_id': 1, 'is_remote': False},
'parent': None,
'start_time': 1000000000,
'end_time': 1000000000,
'attributes': {
'logfire.span_type': 'log',
'logfire.level_num': 13,
'logfire.msg_template': """\
Failed to introspect calling code. Please report this issue to Logfire. Falling back to normal message formatting which may result in loss of information if using an f-string. Set inspect_arguments=False in logfire.configure() to suppress this warning. The problem was:
No source code available. This happens when running in an interactive shell, using exec(), or running .pyc files without the source .py files.\
""",
'logfire.msg': """\
Failed to introspect calling code. Please report this issue to Logfire. Falling back to normal message formatting which may result in loss of information if using an f-string. Set inspect_arguments=False in logfire.configure() to suppress this warning. The problem was:
No source code available. This happens when running in an interactive shell, using exec(), or running .pyc files without the source .py files.\
""",
'code.filepath': 'tests/test_source_code_extraction.py',
'code.function': 'test_source_code_extraction_module',
'code.lineno': 123,
},
},
{
'name': 'from module',
'context': {'trace_id': 2, 'span_id': 2, 'is_remote': False},
'parent': None,
'start_time': 2000000000,
'end_time': 3000000000,
'attributes': {
'code.filepath': 'tests/test_source_code_extraction.py',
'code.function': 'test_source_code_extraction_module',
'code.lineno': 123,
'logfire.msg_template': 'from module',
'logfire.msg': 'from module',
'logfire.span_type': 'span',
},
},
]
)
def test_source_code_extraction_exec_no_inspect_arguments(
exporter: TestExporter, config_kwargs: dict[str, Any]
) -> None:
config_kwargs['inspect_arguments'] = False
logfire.configure(**config_kwargs)
exec(
"""import logfire
with logfire.span('from module'):
pass
"""
)
assert normalize_filepaths(
exporter.exported_spans_as_dict(strip_filepaths=False, _strip_function_qualname=False)
) == snapshot(
[
{
'name': 'from module',
'context': {'trace_id': 1, 'span_id': 1, 'is_remote': False},
'parent': None,
'start_time': 1000000000,
'end_time': 2000000000,
'attributes': {
'code.filepath': 'tests/test_source_code_extraction.py',
'code.function': 'test_source_code_extraction_exec_no_inspect_arguments',
'code.lineno': 123,
'logfire.msg_template': 'from module',
'logfire.span_type': 'span',
'logfire.msg': 'from module',
},
}
]
)
def test_source_code_extraction_nested(exporter: TestExporter) -> None:
nested()
code_function = 'nested.<locals>.bar.<locals>.AClass.method' if sys.version_info >= (3, 11) else 'method'
assert normalize_filepaths(
exporter.exported_spans_as_dict(strip_filepaths=False, fixed_line_number=None, _strip_function_qualname=False)
) == snapshot(
[
{
'name': 'hi!',
'context': {'trace_id': 1, 'span_id': 1, 'is_remote': False},
'parent': None,
'start_time': 1000000000,
'end_time': 2000000000,
'attributes': {
'code.filepath': 'tests/test_source_code_extraction.py',
'code.lineno': 29,
'code.function': code_function,
'logfire.msg_template': 'hi!',
'logfire.span_type': 'span',
'logfire.msg': 'hi!',
},
}
]
)