Skip to content

Commit 28d8b82

Browse files
authored
Remove 3.6 compat (#3517)
* Remove 3.6 compat * fix
1 parent 3ce8065 commit 28d8b82

File tree

10 files changed

+54
-171
lines changed

10 files changed

+54
-171
lines changed

scripts/init_serverless_sdk.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ def extract_and_load_lambda_function_module(self, module_path):
5050
module_name = module_path.split(os.path.sep)[-1]
5151
module_file_path = module_path + ".py"
5252

53-
# Supported python versions are 3.6, 3.7, 3.8
54-
if py_version >= (3, 6):
53+
# Supported python versions are 3.7, 3.8
54+
if py_version >= (3, 7):
5555
import importlib.util
5656

5757
spec = importlib.util.spec_from_file_location(

sentry_sdk/_compat.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
T = TypeVar("T")
1010

1111

12-
PY37 = sys.version_info[0] == 3 and sys.version_info[1] >= 7
1312
PY310 = sys.version_info[0] == 3 and sys.version_info[1] >= 10
1413
PY311 = sys.version_info[0] == 3 and sys.version_info[1] >= 11
1514

sentry_sdk/client.py

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from importlib import import_module
88
from typing import cast
99

10-
from sentry_sdk._compat import PY37, check_uwsgi_thread_support
10+
from sentry_sdk._compat import check_uwsgi_thread_support
1111
from sentry_sdk.utils import (
1212
ContextVar,
1313
capture_internal_exceptions,
@@ -18,7 +18,6 @@
1818
get_type_name,
1919
get_default_release,
2020
handle_in_app,
21-
is_gevent,
2221
logger,
2322
)
2423
from sentry_sdk.serializer import serialize
@@ -132,14 +131,6 @@ def _get_options(*args, **kwargs):
132131
return rv
133132

134133

135-
try:
136-
# Python 3.6+
137-
module_not_found_error = ModuleNotFoundError
138-
except Exception:
139-
# Older Python versions
140-
module_not_found_error = ImportError # type: ignore
141-
142-
143134
class BaseClient:
144135
"""
145136
.. versionadded:: 2.0.0
@@ -264,7 +255,7 @@ def _setup_instrumentation(self, functions_to_trace):
264255
function_obj = getattr(module_obj, function_name)
265256
setattr(module_obj, function_name, trace(function_obj))
266257
logger.debug("Enabled tracing for %s", function_qualname)
267-
except module_not_found_error:
258+
except ModuleNotFoundError:
268259
try:
269260
# Try to import a class
270261
# ex: "mymodule.submodule.MyClassName.member_function"
@@ -320,22 +311,14 @@ def _capture_envelope(envelope):
320311
self.metrics_aggregator = None # type: Optional[MetricsAggregator]
321312
experiments = self.options.get("_experiments", {})
322313
if experiments.get("enable_metrics", True):
323-
# Context vars are not working correctly on Python <=3.6
324-
# with gevent.
325-
metrics_supported = not is_gevent() or PY37
326-
if metrics_supported:
327-
from sentry_sdk.metrics import MetricsAggregator
314+
from sentry_sdk.metrics import MetricsAggregator
328315

329-
self.metrics_aggregator = MetricsAggregator(
330-
capture_func=_capture_envelope,
331-
enable_code_locations=bool(
332-
experiments.get("metric_code_locations", True)
333-
),
334-
)
335-
else:
336-
logger.info(
337-
"Metrics not supported on Python 3.6 and lower with gevent."
338-
)
316+
self.metrics_aggregator = MetricsAggregator(
317+
capture_func=_capture_envelope,
318+
enable_code_locations=bool(
319+
experiments.get("metric_code_locations", True)
320+
),
321+
)
339322

340323
max_request_body_size = ("always", "never", "small", "medium")
341324
if self.options["max_request_body_size"] not in max_request_body_size:

sentry_sdk/integrations/aws_lambda.py

Lines changed: 27 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -208,77 +208,44 @@ def setup_once():
208208
)
209209
return
210210

211-
pre_37 = hasattr(lambda_bootstrap, "handle_http_request") # Python 3.6
211+
lambda_bootstrap.LambdaRuntimeClient.post_init_error = _wrap_init_error(
212+
lambda_bootstrap.LambdaRuntimeClient.post_init_error
213+
)
212214

213-
if pre_37:
214-
old_handle_event_request = lambda_bootstrap.handle_event_request
215+
old_handle_event_request = lambda_bootstrap.handle_event_request
215216

216-
def sentry_handle_event_request(request_handler, *args, **kwargs):
217-
# type: (Any, *Any, **Any) -> Any
218-
request_handler = _wrap_handler(request_handler)
219-
return old_handle_event_request(request_handler, *args, **kwargs)
220-
221-
lambda_bootstrap.handle_event_request = sentry_handle_event_request
222-
223-
old_handle_http_request = lambda_bootstrap.handle_http_request
224-
225-
def sentry_handle_http_request(request_handler, *args, **kwargs):
226-
# type: (Any, *Any, **Any) -> Any
227-
request_handler = _wrap_handler(request_handler)
228-
return old_handle_http_request(request_handler, *args, **kwargs)
229-
230-
lambda_bootstrap.handle_http_request = sentry_handle_http_request
217+
def sentry_handle_event_request( # type: ignore
218+
lambda_runtime_client, request_handler, *args, **kwargs
219+
):
220+
request_handler = _wrap_handler(request_handler)
221+
return old_handle_event_request(
222+
lambda_runtime_client, request_handler, *args, **kwargs
223+
)
231224

232-
# Patch to_json to drain the queue. This should work even when the
233-
# SDK is initialized inside of the handler
225+
lambda_bootstrap.handle_event_request = sentry_handle_event_request
234226

235-
old_to_json = lambda_bootstrap.to_json
227+
# Patch the runtime client to drain the queue. This should work
228+
# even when the SDK is initialized inside of the handler
236229

237-
def sentry_to_json(*args, **kwargs):
230+
def _wrap_post_function(f):
231+
# type: (F) -> F
232+
def inner(*args, **kwargs):
238233
# type: (*Any, **Any) -> Any
239234
_drain_queue()
240-
return old_to_json(*args, **kwargs)
241-
242-
lambda_bootstrap.to_json = sentry_to_json
243-
else:
244-
lambda_bootstrap.LambdaRuntimeClient.post_init_error = _wrap_init_error(
245-
lambda_bootstrap.LambdaRuntimeClient.post_init_error
246-
)
235+
return f(*args, **kwargs)
247236

248-
old_handle_event_request = lambda_bootstrap.handle_event_request
237+
return inner # type: ignore
249238

250-
def sentry_handle_event_request( # type: ignore
251-
lambda_runtime_client, request_handler, *args, **kwargs
252-
):
253-
request_handler = _wrap_handler(request_handler)
254-
return old_handle_event_request(
255-
lambda_runtime_client, request_handler, *args, **kwargs
256-
)
257-
258-
lambda_bootstrap.handle_event_request = sentry_handle_event_request
259-
260-
# Patch the runtime client to drain the queue. This should work
261-
# even when the SDK is initialized inside of the handler
262-
263-
def _wrap_post_function(f):
264-
# type: (F) -> F
265-
def inner(*args, **kwargs):
266-
# type: (*Any, **Any) -> Any
267-
_drain_queue()
268-
return f(*args, **kwargs)
269-
270-
return inner # type: ignore
271-
272-
lambda_bootstrap.LambdaRuntimeClient.post_invocation_result = (
273-
_wrap_post_function(
274-
lambda_bootstrap.LambdaRuntimeClient.post_invocation_result
275-
)
239+
lambda_bootstrap.LambdaRuntimeClient.post_invocation_result = (
240+
_wrap_post_function(
241+
lambda_bootstrap.LambdaRuntimeClient.post_invocation_result
276242
)
277-
lambda_bootstrap.LambdaRuntimeClient.post_invocation_error = (
278-
_wrap_post_function(
279-
lambda_bootstrap.LambdaRuntimeClient.post_invocation_error
280-
)
243+
)
244+
lambda_bootstrap.LambdaRuntimeClient.post_invocation_error = (
245+
_wrap_post_function(
246+
lambda_bootstrap.LambdaRuntimeClient.post_invocation_error
281247
)
248+
)
282249

283250

284251
def get_lambda_bootstrap():

sentry_sdk/metrics.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from sentry_sdk.utils import (
1717
ContextVar,
1818
now,
19-
nanosecond_time,
2019
to_timestamp,
2120
serialize_frame,
2221
json_dumps,
@@ -362,9 +361,9 @@ def _encode_locations(timestamp, code_locations):
362361

363362
# some of these are dumb
364363
TIMING_FUNCTIONS = {
365-
"nanosecond": nanosecond_time,
366-
"microsecond": lambda: nanosecond_time() / 1000.0,
367-
"millisecond": lambda: nanosecond_time() / 1000000.0,
364+
"nanosecond": time.perf_counter_ns,
365+
"microsecond": lambda: time.perf_counter_ns() / 1000.0,
366+
"millisecond": lambda: time.perf_counter_ns() / 1000000.0,
368367
"second": now,
369368
"minute": lambda: now() / 60.0,
370369
"hour": lambda: now() / 3600.0,

sentry_sdk/profiler/transaction_profiler.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
is_gevent,
4949
is_valid_sample_rate,
5050
logger,
51-
nanosecond_time,
5251
set_in_app_in_frames,
5352
)
5453

@@ -330,7 +329,7 @@ def start(self):
330329
logger.debug("[Profiling] Starting profile")
331330
self.active = True
332331
if not self.start_ns:
333-
self.start_ns = nanosecond_time()
332+
self.start_ns = time.perf_counter_ns()
334333
self.scheduler.start_profiling(self)
335334

336335
def stop(self):
@@ -341,7 +340,7 @@ def stop(self):
341340
assert self.scheduler, "No scheduler specified"
342341
logger.debug("[Profiling] Stopping profile")
343342
self.active = False
344-
self.stop_ns = nanosecond_time()
343+
self.stop_ns = time.perf_counter_ns()
345344

346345
def __enter__(self):
347346
# type: () -> Profile
@@ -580,7 +579,7 @@ def _sample_stack(*args, **kwargs):
580579
# were started after this point.
581580
new_profiles = len(self.new_profiles)
582581

583-
now = nanosecond_time()
582+
now = time.perf_counter_ns()
584583

585584
try:
586585
sample = [

sentry_sdk/scope.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
capture_internal_exception,
3131
capture_internal_exceptions,
3232
ContextVar,
33-
datetime_from_isoformat,
3433
disable_capture_event,
3534
event_from_exception,
3635
exc_info_from_error,
@@ -1258,7 +1257,7 @@ def _apply_breadcrumbs_to_event(self, event, hint, options):
12581257
try:
12591258
for crumb in event["breadcrumbs"]["values"]:
12601259
if isinstance(crumb["timestamp"], str):
1261-
crumb["timestamp"] = datetime_from_isoformat(crumb["timestamp"])
1260+
crumb["timestamp"] = datetime.fromisoformat(crumb["timestamp"])
12621261

12631262
event["breadcrumbs"]["values"].sort(key=lambda crumb: crumb["timestamp"])
12641263
except Exception:

sentry_sdk/tracing.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import uuid
22
import random
3+
import time
34
import warnings
45
from datetime import datetime, timedelta, timezone
56

@@ -15,7 +16,6 @@
1516
get_current_thread_meta,
1617
is_valid_sample_rate,
1718
logger,
18-
nanosecond_time,
1919
)
2020

2121
from typing import TYPE_CHECKING, cast
@@ -303,7 +303,7 @@ def __init__(
303303
try:
304304
# profiling depends on this value and requires that
305305
# it is measured in nanoseconds
306-
self._start_timestamp_monotonic_ns = nanosecond_time()
306+
self._start_timestamp_monotonic_ns = time.perf_counter_ns()
307307
except AttributeError:
308308
pass
309309

@@ -612,7 +612,7 @@ def finish(self, scope=None, end_timestamp=None):
612612
end_timestamp = datetime.fromtimestamp(end_timestamp, timezone.utc)
613613
self.timestamp = end_timestamp
614614
else:
615-
elapsed = nanosecond_time() - self._start_timestamp_monotonic_ns
615+
elapsed = time.perf_counter_ns() - self._start_timestamp_monotonic_ns
616616
self.timestamp = self.start_timestamp + timedelta(
617617
microseconds=elapsed / 1000
618618
)

sentry_sdk/utils.py

Lines changed: 6 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
BaseExceptionGroup = None # type: ignore
2626

2727
import sentry_sdk
28-
from sentry_sdk._compat import PY37
2928
from sentry_sdk.consts import DEFAULT_MAX_VALUE_LENGTH, EndpointType
3029

3130
from typing import TYPE_CHECKING
@@ -239,15 +238,6 @@ def format_timestamp(value):
239238
return utctime.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
240239

241240

242-
def datetime_from_isoformat(value):
243-
# type: (str) -> datetime
244-
try:
245-
return datetime.fromisoformat(value)
246-
except AttributeError:
247-
# py 3.6
248-
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")
249-
250-
251241
def event_hint_with_exc_info(exc_info=None):
252242
# type: (Optional[ExcInfo]) -> Dict[str, Optional[ExcInfo]]
253243
"""Creates a hint with the exc info filled in."""
@@ -1325,27 +1315,13 @@ def _get_contextvars():
13251315
See https://docs.sentry.io/platforms/python/contextvars/ for more information.
13261316
"""
13271317
if not _is_contextvars_broken():
1328-
# aiocontextvars is a PyPI package that ensures that the contextvars
1329-
# backport (also a PyPI package) works with asyncio under Python 3.6
1330-
#
1331-
# Import it if available.
1332-
if sys.version_info < (3, 7):
1333-
# `aiocontextvars` is absolutely required for functional
1334-
# contextvars on Python 3.6.
1335-
try:
1336-
from aiocontextvars import ContextVar
1337-
1338-
return True, ContextVar
1339-
except ImportError:
1340-
pass
1341-
else:
1342-
# On Python 3.7 contextvars are functional.
1343-
try:
1344-
from contextvars import ContextVar
1318+
# On Python 3.7+ contextvars are functional.
1319+
try:
1320+
from contextvars import ContextVar
13451321

1346-
return True, ContextVar
1347-
except ImportError:
1348-
pass
1322+
return True, ContextVar
1323+
except ImportError:
1324+
pass
13491325

13501326
# Fall back to basic thread-local usage.
13511327

@@ -1830,19 +1806,6 @@ async def runner(*args: "P.args", **kwargs: "P.kwargs"):
18301806
return patcher
18311807

18321808

1833-
if PY37:
1834-
1835-
def nanosecond_time():
1836-
# type: () -> int
1837-
return time.perf_counter_ns()
1838-
1839-
else:
1840-
1841-
def nanosecond_time():
1842-
# type: () -> int
1843-
return int(time.perf_counter() * 1e9)
1844-
1845-
18461809
def now():
18471810
# type: () -> float
18481811
return time.perf_counter()

0 commit comments

Comments
 (0)