Skip to content

Commit f2d5637

Browse files
authored
fix: Deal with gevent patched thread locals (getsentry#395)
* fix: Deal with gevent patched thread locals * fix: Linters * build: Remove support for sanic 19 See sanic-org/sanic#1532 (comment)
1 parent 9f65ca4 commit f2d5637

File tree

2 files changed

+49
-9
lines changed

2 files changed

+49
-9
lines changed

sentry_sdk/utils.py

+48-7
Original file line numberDiff line numberDiff line change
@@ -734,15 +734,50 @@ def realign_remark(remark):
734734
)
735735

736736

737-
HAS_REAL_CONTEXTVARS = True
737+
def _is_threading_local_monkey_patched():
738+
# type: () -> bool
739+
try:
740+
from gevent.monkey import is_object_patched # type: ignore
741+
742+
if is_object_patched("_threading", "local"):
743+
return True
744+
except ImportError:
745+
pass
746+
747+
try:
748+
from eventlet.patcher import is_monkey_patched # type: ignore
749+
750+
if is_monkey_patched("thread"):
751+
return True
752+
except ImportError:
753+
pass
754+
755+
return False
756+
738757

739-
try:
740-
from contextvars import ContextVar # type: ignore
758+
IS_THREADING_LOCAL_MONKEY_PATCHED = _is_threading_local_monkey_patched()
759+
del _is_threading_local_monkey_patched
741760

742-
if not PY2 and sys.version_info < (3, 7):
743-
import aiocontextvars # type: ignore # noqa
744-
except ImportError:
745-
HAS_REAL_CONTEXTVARS = False
761+
762+
def _get_contextvars():
763+
# () -> (bool, Type)
764+
"""
765+
Try to import contextvars and use it if it's deemed safe. We should not use
766+
contextvars if gevent or eventlet have patched thread locals, as
767+
contextvars are unaffected by that patch.
768+
769+
https://github.com/gevent/gevent/issues/1407
770+
"""
771+
if not IS_THREADING_LOCAL_MONKEY_PATCHED:
772+
try:
773+
from contextvars import ContextVar # type: ignore
774+
775+
if not PY2 and sys.version_info < (3, 7):
776+
import aiocontextvars # type: ignore # noqa
777+
778+
return True, ContextVar
779+
except ImportError:
780+
pass
746781

747782
from threading import local
748783

@@ -759,6 +794,12 @@ def get(self, default):
759794
def set(self, value):
760795
setattr(self._local, "value", value)
761796

797+
return False, ContextVar
798+
799+
800+
HAS_REAL_CONTEXTVARS, ContextVar = _get_contextvars()
801+
del _get_contextvars
802+
762803

763804
def transaction_from_function(func):
764805
# type: (Callable[..., Any]) -> Optional[str]

tox.ini

+1-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ envlist =
2727
{pypy,py2.7,py3.5,py3.6,py3.7,py3.8}-falcon-1.4
2828
{pypy,py2.7,py3.5,py3.6,py3.7,py3.8}-falcon-2.0
2929

30-
{py3.5,py3.6,py3.7}-sanic-{0.8,18,19}
30+
{py3.5,py3.6,py3.7}-sanic-{0.8,18}
3131

3232
{pypy,py2.7,py3.5,py3.6,py3.7,py3.8}-celery-{4.1,4.2,4.3}
3333
{pypy,py2.7}-celery-3
@@ -79,7 +79,6 @@ deps =
7979

8080
sanic-0.8: sanic>=0.8,<0.9
8181
sanic-18: sanic>=18.0,<19.0
82-
sanic-19: sanic>=19.0,<20.0
8382
{py3.5,py3.6}-sanic: aiocontextvars==0.2.1
8483
sanic: aiohttp
8584

0 commit comments

Comments
 (0)