@@ -734,15 +734,50 @@ def realign_remark(remark):
734
734
)
735
735
736
736
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
+
738
757
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
741
760
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
746
781
747
782
from threading import local
748
783
@@ -759,6 +794,12 @@ def get(self, default):
759
794
def set (self , value ):
760
795
setattr (self ._local , "value" , value )
761
796
797
+ return False , ContextVar
798
+
799
+
800
+ HAS_REAL_CONTEXTVARS , ContextVar = _get_contextvars ()
801
+ del _get_contextvars
802
+
762
803
763
804
def transaction_from_function (func ):
764
805
# type: (Callable[..., Any]) -> Optional[str]
0 commit comments