Skip to content
Draft
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
2 changes: 1 addition & 1 deletion scripts/build_aws_lambda_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def install_python_packages(self) -> None:

sentry_python_sdk = os.path.join(
DIST_PATH,
f"sentry_sdk-{SDK_VERSION}-py2.py3-none-any.whl", # this is generated by "make dist" that is called by "make aws-lambda-layer"
f"sentry_sdk-{SDK_VERSION}-py3-none-any.whl", # this is generated by "make dist" that is called by "make aws-lambda-layer"
)
subprocess.run(
[
Expand Down
16 changes: 0 additions & 16 deletions sentry_sdk/_compat.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,12 @@
import sys

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from typing import Any
from typing import TypeVar

T = TypeVar("T")


PY37 = sys.version_info[0] == 3 and sys.version_info[1] >= 7
PY38 = sys.version_info[0] == 3 and sys.version_info[1] >= 8
PY310 = sys.version_info[0] == 3 and sys.version_info[1] >= 10
PY311 = sys.version_info[0] == 3 and sys.version_info[1] >= 11


def with_metaclass(meta: "Any", *bases: "Any") -> "Any":
class MetaClass(type):
def __new__(metacls: "Any", name: "Any", this_bases: "Any", d: "Any") -> "Any":
return meta(name, bases, d)

return type.__new__(MetaClass, "temporary_class", (), {})


def check_uwsgi_thread_support() -> bool:
# We check two things here:
#
Expand Down
12 changes: 2 additions & 10 deletions sentry_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,6 @@ def _get_options(*args: "Optional[str]", **kwargs: "Any") -> "Dict[str, Any]":
return rv


try:
# Python 3.6+
module_not_found_error = ModuleNotFoundError
except Exception:
# Older Python versions
module_not_found_error = ImportError # type: ignore


class BaseClient:
"""
.. versionadded:: 2.0.0
Expand Down Expand Up @@ -289,7 +281,7 @@ class _Client(BaseClient):
"""

def __init__(self, *args: "Any", **kwargs: "Any") -> None:
super(_Client, self).__init__(options=get_options(*args, **kwargs))
super().__init__(options=get_options(*args, **kwargs))
self._init_impl()

def __getstate__(self) -> "Any":
Expand Down Expand Up @@ -318,7 +310,7 @@ def _setup_instrumentation(
function_obj = getattr(module_obj, function_name)
setattr(module_obj, function_name, trace(function_obj))
logger.debug("Enabled tracing for %s", function_qualname)
except module_not_found_error:
except ModuleNotFoundError:
try:
# Try to import a class
# ex: "mymodule.submodule.MyClassName.member_function"
Expand Down
3 changes: 1 addition & 2 deletions sentry_sdk/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
get_global_scope,
get_isolation_scope,
)
from sentry_sdk._compat import with_metaclass
from sentry_sdk.client import Client
from sentry_sdk.consts import INSTRUMENTER
from sentry_sdk.scope import _ScopeManager
Expand Down Expand Up @@ -109,7 +108,7 @@ def main(cls) -> "Hub":
return GLOBAL_HUB


class Hub(with_metaclass(HubMeta)): # type: ignore
class Hub(metaclass=HubMeta):
"""
.. deprecated:: 2.0.0
The Hub is deprecated. Its functionality will be merged into :py:class:`sentry_sdk.scope.Scope`.
Expand Down
1 change: 0 additions & 1 deletion sentry_sdk/integrations/django/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ def sentry_wrapped_method(*args: "Any", **kwargs: "Any") -> "Any":
return old_method(*args, **kwargs)

try:
# fails for __call__ of function on Python 2 (see py2.7-django-1.11)
sentry_wrapped_method = wraps(old_method)(sentry_wrapped_method)

# Necessary for Django 3.1
Expand Down
2 changes: 0 additions & 2 deletions sentry_sdk/integrations/django/signals_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ def _get_receiver_name(receiver: "Callable[..., Any]") -> str:

if hasattr(receiver, "__qualname__"):
name = receiver.__qualname__
elif hasattr(receiver, "__name__"): # Python 2.7 has no __qualname__
name = receiver.__name__
elif hasattr(
receiver, "func"
): # certain functions (like partials) dont have a name
Expand Down
11 changes: 3 additions & 8 deletions sentry_sdk/integrations/django/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
from typing import Any


try:
from asyncio import iscoroutinefunction
except ImportError:
iscoroutinefunction = None # type: ignore
from asyncio import iscoroutinefunction


try:
Expand Down Expand Up @@ -48,10 +45,8 @@ def sentry_patched_make_view_atomic(

integration = sentry_sdk.get_client().get_integration(DjangoIntegration)
if integration is not None:
is_async_view = (
iscoroutinefunction is not None
and wrap_async_view is not None
and iscoroutinefunction(callback)
is_async_view = wrap_async_view is not None and iscoroutinefunction(
callback
)
if is_async_view:
sentry_wrapped_callback = wrap_async_view(callback)
Expand Down
9 changes: 3 additions & 6 deletions sentry_sdk/traces.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,12 +278,9 @@ def __init__(
self._start_timestamp = datetime.now(timezone.utc)
self._timestamp: "Optional[datetime]" = None

try:
# profiling depends on this value and requires that
# it is measured in nanoseconds
self._start_timestamp_monotonic_ns = nanosecond_time()
except AttributeError:
pass
# profiling depends on this value and requires that
# it is measured in nanoseconds
self._start_timestamp_monotonic_ns = nanosecond_time()

self._span_id: "Optional[str]" = None

Expand Down
30 changes: 12 additions & 18 deletions sentry_sdk/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,12 +327,9 @@ def __init__(
elif isinstance(start_timestamp, float):
start_timestamp = datetime.fromtimestamp(start_timestamp, timezone.utc)
self.start_timestamp = start_timestamp
try:
# profiling depends on this value and requires that
# it is measured in nanoseconds
self._start_timestamp_monotonic_ns = nanosecond_time()
except AttributeError:
pass
# profiling depends on this value and requires that
# it is measured in nanoseconds
self._start_timestamp_monotonic_ns = nanosecond_time()

#: End timestamp of span
self.timestamp: "Optional[datetime]" = None
Expand Down Expand Up @@ -661,18 +658,15 @@ def finish(
# This span is already finished, ignore.
return None

try:
if end_timestamp:
if isinstance(end_timestamp, float):
end_timestamp = datetime.fromtimestamp(end_timestamp, timezone.utc)
self.timestamp = end_timestamp
else:
elapsed = nanosecond_time() - self._start_timestamp_monotonic_ns
self.timestamp = self.start_timestamp + timedelta(
microseconds=elapsed / 1000
)
except AttributeError:
self.timestamp = datetime.now(timezone.utc)
if end_timestamp:
if isinstance(end_timestamp, float):
end_timestamp = datetime.fromtimestamp(end_timestamp, timezone.utc)
self.timestamp = end_timestamp
else:
elapsed = nanosecond_time() - self._start_timestamp_monotonic_ns
self.timestamp = self.start_timestamp + timedelta(
microseconds=elapsed / 1000
)

scope = scope or sentry_sdk.get_current_scope()

Expand Down
19 changes: 3 additions & 16 deletions sentry_sdk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def get_git_revision() -> "Optional[str]":
.strip()
.decode("utf-8")
)
except (OSError, IOError, FileNotFoundError):
except OSError:
return None

return revision
Expand Down Expand Up @@ -492,15 +492,15 @@ def get_lines_from_file(
if loader is not None and hasattr(loader, "get_source"):
try:
source_str: "Optional[str]" = loader.get_source(module)
except (ImportError, IOError):
except (ImportError, OSError):
source_str = None
if source_str is not None:
source = source_str.splitlines()

if source is None:
try:
source = linecache.getlines(filename)
except (OSError, IOError):
except OSError:
return [], None, []

if not source:
Expand Down Expand Up @@ -1472,16 +1472,6 @@ def qualname_from_function(func: "Callable[..., Any]") -> "Optional[str]":
"""Return the qualified name of func. Works with regular function, lambda, partial and partialmethod."""
func_qualname: "Optional[str]" = None

# Python 2
try:
return "%s.%s.%s" % (
func.im_class.__module__, # type: ignore
func.im_class.__name__, # type: ignore
func.__name__,
)
except Exception:
pass

prefix, suffix = "", ""

if isinstance(func, partial) and hasattr(func.func, "__name__"):
Expand All @@ -1499,10 +1489,7 @@ def qualname_from_function(func: "Callable[..., Any]") -> "Optional[str]":

if hasattr(func, "__qualname__"):
func_qualname = func.__qualname__
elif hasattr(func, "__name__"): # Python 2.7 has no __qualname__
func_qualname = func.__name__

# Python 3: methods, functions, classes
if func_qualname is not None:
if hasattr(func, "__module__") and isinstance(func.__module__, str):
func_qualname = func.__module__ + "." + func_qualname
Expand Down
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,4 @@ def get_file_text(file_name):
"Programming Language :: Python :: 3.14",
"Topic :: Software Development :: Libraries :: Python Modules",
],
options={"bdist_wheel": {"universal": "1"}},
)
7 changes: 2 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,6 @@ def __eq__(self, test_string):
if not isinstance(test_string, self.valid_types):
return False

# this is safe even in py2 because as of 2.6, `bytes` exists in py2
# as an alias for `str`
if isinstance(test_string, bytes):
test_string = test_string.decode()

Expand All @@ -548,9 +546,8 @@ def _safe_is_equal(x, y):
Compares two values, preferring to use the first's __eq__ method if it
exists and is implemented.

Accounts for py2/py3 differences (like ints in py2 not having a __eq__
method), as well as the incomparability of certain types exposed by using
raw __eq__ () rather than ==.
Accounts for the incomparability of certain types exposed by using raw
__eq__ () rather than ==.
"""

# Prefer using __eq__ directly to ensure that examples like
Expand Down
Loading