Skip to content

Removing utcnow method deprecated at python3.12 #2415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions sentry_sdk/_compat.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import sys
import contextlib
from datetime import datetime
from functools import wraps

from sentry_sdk._types import TYPE_CHECKING
Expand Down Expand Up @@ -32,6 +33,12 @@
iteritems = lambda x: x.iteritems() # noqa: B301
binary_sequence_types = (bytearray, memoryview)

def datetime_utcnow():
return datetime.utcnow()

def utc_from_timestamp(timestamp):
return datetime.utcfromtimestamp(timestamp)

def implements_str(cls):
# type: (T) -> T
cls.__unicode__ = cls.__str__
Expand Down Expand Up @@ -78,6 +85,7 @@ def when_called(*args, **kwargs):
return DecoratorContextManager

else:
from datetime import timezone
import urllib.parse as urlparse # noqa

text_type = str
Expand All @@ -87,6 +95,14 @@ def when_called(*args, **kwargs):
iteritems = lambda x: x.items()
binary_sequence_types = (bytes, bytearray, memoryview)

def datetime_utcnow():
# type: () -> datetime
return datetime.now(timezone.utc)

def utc_from_timestamp(timestamp):
# type: (float) -> datetime
return datetime.fromtimestamp(timestamp, timezone.utc)

def implements_str(x):
# type: (T) -> T
return x
Expand Down
7 changes: 3 additions & 4 deletions sentry_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
import os
import uuid
import random
from datetime import datetime
import socket

from sentry_sdk._compat import string_types, text_type, iteritems
from sentry_sdk._compat import datetime_utcnow, string_types, text_type, iteritems
from sentry_sdk.utils import (
capture_internal_exceptions,
current_stacktrace,
Expand Down Expand Up @@ -292,7 +291,7 @@ def _prepare_event(
# type: (...) -> Optional[Event]

if event.get("timestamp") is None:
event["timestamp"] = datetime.utcnow()
event["timestamp"] = datetime_utcnow()

if scope is not None:
is_transaction = event.get("type") == "transaction"
Expand Down Expand Up @@ -568,7 +567,7 @@ def capture_event(
if should_use_envelope_endpoint:
headers = {
"event_id": event_opt["event_id"],
"sent_at": format_timestamp(datetime.utcnow()),
"sent_at": format_timestamp(datetime_utcnow()),
}

if dynamic_sampling_context:
Expand Down
5 changes: 3 additions & 2 deletions sentry_sdk/db/explain_plan/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import datetime

from sentry_sdk._compat import datetime_utcnow
from sentry_sdk.consts import TYPE_CHECKING

if TYPE_CHECKING:
Expand All @@ -15,7 +16,7 @@ def cache_statement(statement, options):
# type: (str, dict[str, Any]) -> None
global EXPLAIN_CACHE

now = datetime.datetime.utcnow()
now = datetime_utcnow()
explain_cache_timeout_seconds = options.get(
"explain_cache_timeout_seconds", EXPLAIN_CACHE_TIMEOUT_SECONDS
)
Expand All @@ -31,7 +32,7 @@ def remove_expired_cache_items():
"""
global EXPLAIN_CACHE

now = datetime.datetime.utcnow()
now = datetime_utcnow()

for key, expiration_time in EXPLAIN_CACHE.items():
expiration_in_the_past = expiration_time < now
Expand Down
5 changes: 2 additions & 3 deletions sentry_sdk/hub.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import copy
import sys

from datetime import datetime
from contextlib import contextmanager

from sentry_sdk._compat import with_metaclass
from sentry_sdk._compat import datetime_utcnow, with_metaclass
from sentry_sdk.consts import INSTRUMENTER
from sentry_sdk.scope import Scope
from sentry_sdk.client import Client
Expand Down Expand Up @@ -439,7 +438,7 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs):
hint = dict(hint or ()) # type: Hint

if crumb.get("timestamp") is None:
crumb["timestamp"] = datetime.utcnow()
crumb["timestamp"] = datetime_utcnow()
if crumb.get("type") is None:
crumb["type"] = "default"

Expand Down
9 changes: 5 additions & 4 deletions sentry_sdk/integrations/aws_lambda.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import sys
from copy import deepcopy
from datetime import datetime, timedelta
from datetime import timedelta
from os import environ

from sentry_sdk.api import continue_trace
Expand All @@ -16,10 +16,11 @@
)
from sentry_sdk.integrations import Integration
from sentry_sdk.integrations._wsgi_common import _filter_headers
from sentry_sdk._compat import reraise
from sentry_sdk._compat import datetime_utcnow, reraise
from sentry_sdk._types import TYPE_CHECKING

if TYPE_CHECKING:
from datetime import datetime
from typing import Any
from typing import TypeVar
from typing import Callable
Expand Down Expand Up @@ -323,7 +324,7 @@ def get_lambda_bootstrap():

def _make_request_event_processor(aws_event, aws_context, configured_timeout):
# type: (Any, Any, Any) -> EventProcessor
start_time = datetime.utcnow()
start_time = datetime_utcnow()

def event_processor(sentry_event, hint, start_time=start_time):
# type: (Event, Hint, datetime) -> Optional[Event]
Expand Down Expand Up @@ -428,7 +429,7 @@ def _get_cloudwatch_logs_url(aws_context, start_time):
log_group=aws_context.log_group_name,
log_stream=aws_context.log_stream_name,
start_time=(start_time - timedelta(seconds=1)).strftime(formatstring),
end_time=(datetime.utcnow() + timedelta(seconds=2)).strftime(formatstring),
end_time=(datetime_utcnow() + timedelta(seconds=2)).strftime(formatstring),
)

return url
9 changes: 5 additions & 4 deletions sentry_sdk/integrations/gcp.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import sys
from copy import deepcopy
from datetime import datetime, timedelta
from datetime import timedelta
from os import environ

from sentry_sdk.api import continue_trace
from sentry_sdk.consts import OP
from sentry_sdk.hub import Hub, _should_send_default_pii
from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT
from sentry_sdk._compat import reraise
from sentry_sdk._compat import datetime_utcnow, reraise
from sentry_sdk.utils import (
AnnotatedValue,
capture_internal_exceptions,
Expand All @@ -25,6 +25,7 @@
MILLIS_TO_SECONDS = 1000.0

if TYPE_CHECKING:
from datetime import datetime
from typing import Any
from typing import TypeVar
from typing import Callable
Expand Down Expand Up @@ -57,7 +58,7 @@ def sentry_func(functionhandler, gcp_event, *args, **kwargs):

configured_time = int(configured_time)

initial_time = datetime.utcnow()
initial_time = datetime_utcnow()

with hub.push_scope() as scope:
with capture_internal_exceptions():
Expand Down Expand Up @@ -154,7 +155,7 @@ def _make_request_event_processor(gcp_event, configured_timeout, initial_time):
def event_processor(event, hint):
# type: (Event, Hint) -> Optional[Event]

final_time = datetime.utcnow()
final_time = datetime_utcnow()
time_diff = final_time - initial_time

execution_duration_in_millis = time_diff.microseconds / MILLIS_TO_SECONDS
Expand Down
5 changes: 2 additions & 3 deletions sentry_sdk/integrations/logging.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import absolute_import

import logging
import datetime
from fnmatch import fnmatch

from sentry_sdk.hub import Hub
Expand All @@ -12,7 +11,7 @@
capture_internal_exceptions,
)
from sentry_sdk.integrations import Integration
from sentry_sdk._compat import iteritems
from sentry_sdk._compat import iteritems, utc_from_timestamp

from sentry_sdk._types import TYPE_CHECKING

Expand Down Expand Up @@ -282,6 +281,6 @@ def _breadcrumb_from_record(self, record):
"level": self._logging_to_event_level(record),
"category": record.name,
"message": record.message,
"timestamp": datetime.datetime.utcfromtimestamp(record.created),
"timestamp": utc_from_timestamp(record.created),
"data": self._extra_from_record(record),
}
7 changes: 4 additions & 3 deletions sentry_sdk/session.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import uuid
from datetime import datetime

from sentry_sdk._compat import datetime_utcnow
from sentry_sdk._types import TYPE_CHECKING
from sentry_sdk.utils import format_timestamp

if TYPE_CHECKING:
from datetime import datetime
from typing import Optional
from typing import Union
from typing import Any
Expand Down Expand Up @@ -48,7 +49,7 @@ def __init__(
if sid is None:
sid = uuid.uuid4()
if started is None:
started = datetime.utcnow()
started = datetime_utcnow()
if status is None:
status = "ok"
self.status = status
Expand Down Expand Up @@ -108,7 +109,7 @@ def update(
if did is not None:
self.did = str(did)
if timestamp is None:
timestamp = datetime.utcnow()
timestamp = datetime_utcnow()
self.timestamp = timestamp
if started is not None:
self.started = started
Expand Down
9 changes: 5 additions & 4 deletions sentry_sdk/tracing.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import uuid
import random

from datetime import datetime, timedelta
from datetime import timedelta

import sentry_sdk
from sentry_sdk.consts import INSTRUMENTER
from sentry_sdk.utils import is_valid_sample_rate, logger, nanosecond_time
from sentry_sdk._compat import PY2
from sentry_sdk._compat import datetime_utcnow, PY2
from sentry_sdk.consts import SPANDATA
from sentry_sdk._types import TYPE_CHECKING


if TYPE_CHECKING:
import typing

from datetime import datetime
from typing import Any
from typing import Dict
from typing import Iterator
Expand Down Expand Up @@ -145,7 +146,7 @@ def __init__(
self._tags = {} # type: Dict[str, str]
self._data = {} # type: Dict[str, Any]
self._containing_transaction = containing_transaction
self.start_timestamp = start_timestamp or datetime.utcnow()
self.start_timestamp = start_timestamp or datetime_utcnow()
try:
# profiling depends on this value and requires that
# it is measured in nanoseconds
Expand Down Expand Up @@ -469,7 +470,7 @@ def finish(self, hub=None, end_timestamp=None):
microseconds=elapsed / 1000
)
except AttributeError:
self.timestamp = datetime.utcnow()
self.timestamp = datetime_utcnow()

maybe_create_breadcrumbs_from_span(hub, self)
return None
Expand Down
12 changes: 7 additions & 5 deletions sentry_sdk/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@
import gzip
import time

from datetime import datetime, timedelta
from datetime import timedelta
from collections import defaultdict

from sentry_sdk.utils import Dsn, logger, capture_internal_exceptions, json_dumps
from sentry_sdk.worker import BackgroundWorker
from sentry_sdk.envelope import Envelope, Item, PayloadRef

from sentry_sdk._compat import datetime_utcnow
from sentry_sdk._types import TYPE_CHECKING

if TYPE_CHECKING:
from datetime import datetime
from typing import Any
from typing import Callable
from typing import Dict
Expand Down Expand Up @@ -122,7 +124,7 @@ def __del__(self):
def _parse_rate_limits(header, now=None):
# type: (Any, Optional[datetime]) -> Iterable[Tuple[DataCategory, datetime]]
if now is None:
now = datetime.utcnow()
now = datetime_utcnow()

for limit in header.split(","):
try:
Expand Down Expand Up @@ -209,7 +211,7 @@ def _update_rate_limits(self, response):
# sentries if a proxy in front wants to globally slow things down.
elif response.status == 429:
logger.warning("Rate-limited via 429")
self._disabled_until[None] = datetime.utcnow() + timedelta(
self._disabled_until[None] = datetime_utcnow() + timedelta(
seconds=self._retry.get_retry_after(response) or 60
)

Expand Down Expand Up @@ -316,13 +318,13 @@ def _check_disabled(self, category):
def _disabled(bucket):
# type: (Any) -> bool
ts = self._disabled_until.get(bucket)
return ts is not None and ts > datetime.utcnow()
return ts is not None and ts > datetime_utcnow()

return _disabled(category) or _disabled(None)

def _is_rate_limited(self):
# type: () -> bool
return any(ts > datetime.utcnow() for ts in self._disabled_until.values())
return any(ts > datetime_utcnow() for ts in self._disabled_until.values())

def _is_worker_full(self):
# type: () -> bool
Expand Down
3 changes: 2 additions & 1 deletion tests/test_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from pytest_localserver.http import WSGIServer

from sentry_sdk import Hub, Client, add_breadcrumb, capture_message, Scope
from sentry_sdk._compat import datetime_utcnow
from sentry_sdk.transport import _parse_rate_limits
from sentry_sdk.envelope import Envelope, parse_json
from sentry_sdk.integrations.logging import LoggingIntegration
Expand Down Expand Up @@ -118,7 +119,7 @@ def test_transport_works(
Hub.current.bind_client(client)
request.addfinalizer(lambda: Hub.current.bind_client(None))

add_breadcrumb(level="info", message="i like bread", timestamp=datetime.utcnow())
add_breadcrumb(level="info", message="i like bread", timestamp=datetime_utcnow())
capture_message("löl")

getattr(client, client_flush_method)()
Expand Down