Skip to content

ref(init): Move sentry_sdk.init out of hub.py #3276

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 1 commit into from
Jul 16, 2024
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
3 changes: 2 additions & 1 deletion sentry_sdk/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from sentry_sdk.hub import Hub, init
from sentry_sdk.hub import Hub
from sentry_sdk.scope import Scope
from sentry_sdk.transport import Transport, HttpTransport
from sentry_sdk.client import Client
from sentry_sdk._init_implementation import init

from sentry_sdk.api import * # noqa

Expand Down
63 changes: 63 additions & 0 deletions sentry_sdk/_init_implementation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from typing import TYPE_CHECKING

import sentry_sdk

if TYPE_CHECKING:
from typing import Any, ContextManager, Optional

import sentry_sdk.consts


class _InitGuard:
def __init__(self, client):
# type: (sentry_sdk.Client) -> None
self._client = client

def __enter__(self):
# type: () -> _InitGuard
return self

def __exit__(self, exc_type, exc_value, tb):
# type: (Any, Any, Any) -> None
c = self._client
if c is not None:
c.close()


def _check_python_deprecations():
# type: () -> None
# Since we're likely to deprecate Python versions in the future, I'm keeping
# this handy function around. Use this to detect the Python version used and
# to output logger.warning()s if it's deprecated.
pass


def _init(*args, **kwargs):
# type: (*Optional[str], **Any) -> ContextManager[Any]
"""Initializes the SDK and optionally integrations.

This takes the same arguments as the client constructor.
"""
client = sentry_sdk.Client(*args, **kwargs)
sentry_sdk.Scope.get_global_scope().set_client(client)
_check_python_deprecations()
rv = _InitGuard(client)
return rv


if TYPE_CHECKING:
# Make mypy, PyCharm and other static analyzers think `init` is a type to
# have nicer autocompletion for params.
#
# Use `ClientConstructor` to define the argument types of `init` and
# `ContextManager[Any]` to tell static analyzers about the return type.
Comment on lines +52 to +53
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is inaccurate, since we actually use _InitGuard in the class definition. However, since I am just copying this code over from hub for now, I think it is out of scope to fix here. Perhaps, we can consider fixing in a separate PR later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't really know what the purpose of the _InitGuard is since we never tell people to do the following anywhere, so this is just vague unadvertised functionality.

with sentry_sdk.init():
    pass

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, perhaps we should explicitly deprecate this context manager functionality and remove in the next major, in that case? Or is this a potentially valuable feature we should advertise more?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

init is generally one per process anyway. In case people want DSN isolation, multiple clients is the way to go now. So I really don't see the use case for this.
Let's deprecate and remove.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sl0thentr0py, I opened an issue to make this change, since I think it belongs in a separate PR. Would appreciate an approval here if everything else looks good to you.


class init(sentry_sdk.consts.ClientConstructor, _InitGuard): # noqa: N801
pass

else:
# Alias `init` for actual usage. Go through the lambda indirection to throw
# PyCharm off of the weakly typed signature (it would otherwise discover
# both the weakly typed signature of `_init` and our faked `init` type).

init = (lambda: _init)()
58 changes: 0 additions & 58 deletions sentry_sdk/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
LogLevelStr,
SamplingContext,
)
from sentry_sdk.consts import ClientConstructor
from sentry_sdk.tracing import TransactionKwargs

T = TypeVar("T")
Expand All @@ -59,63 +58,6 @@ def overload(x):
_local = ContextVar("sentry_current_hub")


class _InitGuard:
def __init__(self, client):
# type: (Client) -> None
self._client = client

def __enter__(self):
# type: () -> _InitGuard
return self

def __exit__(self, exc_type, exc_value, tb):
# type: (Any, Any, Any) -> None
c = self._client
if c is not None:
c.close()


def _check_python_deprecations():
# type: () -> None
# Since we're likely to deprecate Python versions in the future, I'm keeping
# this handy function around. Use this to detect the Python version used and
# to output logger.warning()s if it's deprecated.
pass


def _init(*args, **kwargs):
# type: (*Optional[str], **Any) -> ContextManager[Any]
"""Initializes the SDK and optionally integrations.

This takes the same arguments as the client constructor.
"""
client = Client(*args, **kwargs)
Scope.get_global_scope().set_client(client)
_check_python_deprecations()
rv = _InitGuard(client)
return rv


from sentry_sdk._types import TYPE_CHECKING

if TYPE_CHECKING:
# Make mypy, PyCharm and other static analyzers think `init` is a type to
# have nicer autocompletion for params.
#
# Use `ClientConstructor` to define the argument types of `init` and
# `ContextManager[Any]` to tell static analyzers about the return type.

class init(ClientConstructor, _InitGuard): # noqa: N801
pass

else:
# Alias `init` for actual usage. Go through the lambda indirection to throw
# PyCharm off of the weakly typed signature (it would otherwise discover
# both the weakly typed signature of `_init` and our faked `init` type).

init = (lambda: _init)()


class HubMeta(type):
@property
def current(cls):
Expand Down
Loading