# Path: opentracing_instrumentation/request_context.py
# def get_current_span():
#     """
#     Access current request context and extract current Span from it.
#     :return:
#         Return current span associated with the current request context.
#         If no request context is present in thread local, or the context
#         has no span, return None.
#     """
#     # Check against the old, ScopeManager-less implementation,
#     # for backwards compatibility.
#     context = RequestContextManager.current_context()
#     if context is not None:
#         return context.span
# 
#     active = opentracing.tracer.scope_manager.active
#     return active.span if active else None
# 
# def span_in_stack_context(span):
#     """
#     Create Tornado's StackContext that stores the given span in the
#     thread-local request context. This function is intended for use
#     in Tornado applications based on IOLoop, although will work fine
#     in single-threaded apps like Flask, albeit with more overhead.
# 
#     ## Usage example in Tornado application
# 
#     Suppose you have a method `handle_request(request)` in the http server.
#     Instead of calling it directly, use a wrapper:
# 
#     .. code-block:: python
# 
#         from opentracing_instrumentation import request_context
# 
#         @tornado.gen.coroutine
#         def handle_request_wrapper(request, actual_handler, *args, **kwargs)
# 
#             request_wrapper = TornadoRequestWrapper(request=request)
#             span = http_server.before_request(request=request_wrapper)
# 
#             with request_context.span_in_stack_context(span):
#                 return actual_handler(*args, **kwargs)
# 
#     :param span:
#     :return:
#         Return StackContext that wraps the request context.
#     """
# 
#     if not isinstance(opentracing.tracer.scope_manager, TornadoScopeManager):
#         raise RuntimeError('scope_manager is not TornadoScopeManager')
# 
#     # Enter the newly created stack context so we have
#     # storage available for Span activation.
#     context = tracer_stack_context()
#     entered_context = _TracerEnteredStackContext(context)
# 
#     if span is None:
#         return entered_context
# 
#     opentracing.tracer.scope_manager.activate(span, False)
#     assert opentracing.tracer.active_span is not None
#     assert opentracing.tracer.active_span is span
# 
#     return entered_context
# 
# class RequestContext(object):
#     """
#     DEPRECATED, use either span_in_context() or span_in_stack_context()
#     instead.
# 
#     RequestContext represents the context of a request being executed.
# 
#     Useful when a service needs to make downstream calls to other services
#     and requires access to some aspects of the original request, such as
#     tracing information.
# 
#     It is designed to hold a reference to the current OpenTracing Span,
#     but the class can be extended to store more information.
#     """
# 
#     __slots__ = ('span', )
# 
#     def __init__(self, span):
#         self.span = span
# 
# class RequestContextManager(object):
#     """
#     DEPRECATED, use either span_in_context() or span_in_stack_context()
#     instead.
# 
#     A context manager that saves RequestContext in thread-local state.
# 
#     Intended for use with ThreadSafeStackContext (a thread-safe
#     replacement for Tornado's StackContext) or as context manager
#     in a WSGI middleware.
#     """
# 
#     _state = threading.local()
#     _state.context = None
# 
#     @classmethod
#     def current_context(cls):
#         """Get the current request context.
# 
#         :rtype: opentracing_instrumentation.RequestContext
#         :returns: The current request context, or None.
#         """
#         return getattr(cls._state, 'context', None)
# 
#     def __init__(self, context=None, span=None):
#         # normally we want the context parameter, but for backwards
#         # compatibility we make it optional and allow span as well
#         if span:
#             self._context = RequestContext(span=span)
#         elif isinstance(context, opentracing.Span):
#             self._context = RequestContext(span=context)
#         else:
#             self._context = context
# 
#     def __enter__(self):
#         self._prev_context = self.__class__.current_context()
#         self.__class__._state.context = self._context
#         return self._context
# 
#     def __exit__(self, *_):
#         self.__class__._state.context = self._prev_context
#         self._prev_context = None
#         return False


import opentracing
from opentracing.scope_managers.tornado import TornadoScopeManager
from opentracing_instrumentation.request_context import (
    get_current_span,
    span_in_stack_context,
    RequestContext,
    RequestContextManager,
)
from mock import patch
from tornado import gen
from tornado import stack_context
from tornado.testing import AsyncTestCase, gen_test
        span1 = 'Bender is great!'
        span2 = 'Fry is dumb!'

        @gen.coroutine
        def check(span_to_check):
            assert get_current_span() == span_to_check

        with self.assertRaises(Exception):  # passing mismatching spans
            yield run_coroutine_with_span(span1, check, span2)

        @gen.coroutine
        def nested(nested_span_to_check, span_to_check):
            yield run_coroutine_with_span(span1, check, nested_span_to_check)
            assert get_current_span() == span_to_check

        with self.assertRaises(Exception):  # passing mismatching spans
            yield run_coroutine_with_span(span2, nested, span1, span1)
        with self.assertRaises(Exception):  # passing mismatching spans
            yield run_coroutine_with_span(span2, nested, span2, span2)

        # successful case
        yield run_coroutine_with_span(span2, nested, span1, span2)

    def test_no_span(self):
        ctx = RequestContextManager(context=RequestContext(span='x'))
        assert ctx._context.span == 'x'
        assert RequestContextManager.current_context() is None

    def test_backwards_compatible(self):
        span = opentracing.tracer.start_span(operation_name='test')

# Path: opentracing_instrumentation/request_context.py
# def get_current_span():
#     """
#     Access current request context and extract current Span from it.
#     :return:
#         Return current span associated with the current request context.
#         If no request context is present in thread local, or the context
#         has no span, return None.
#     """
#     # Check against the old, ScopeManager-less implementation,
#     # for backwards compatibility.
#     context = RequestContextManager.current_context()
#     if context is not None:
#         return context.span
# 
#     active = opentracing.tracer.scope_manager.active
#     return active.span if active else None
# 
# def span_in_stack_context(span):
#     """
#     Create Tornado's StackContext that stores the given span in the
#     thread-local request context. This function is intended for use
#     in Tornado applications based on IOLoop, although will work fine
#     in single-threaded apps like Flask, albeit with more overhead.
# 
#     ## Usage example in Tornado application
# 
#     Suppose you have a method `handle_request(request)` in the http server.
#     Instead of calling it directly, use a wrapper:
# 
#     .. code-block:: python
# 
#         from opentracing_instrumentation import request_context
# 
#         @tornado.gen.coroutine
#         def handle_request_wrapper(request, actual_handler, *args, **kwargs)
# 
#             request_wrapper = TornadoRequestWrapper(request=request)
#             span = http_server.before_request(request=request_wrapper)
# 
#             with request_context.span_in_stack_context(span):
#                 return actual_handler(*args, **kwargs)
# 
#     :param span:
#     :return:
#         Return StackContext that wraps the request context.
#     """
# 
#     if not isinstance(opentracing.tracer.scope_manager, TornadoScopeManager):
#         raise RuntimeError('scope_manager is not TornadoScopeManager')
# 
#     # Enter the newly created stack context so we have
#     # storage available for Span activation.
#     context = tracer_stack_context()
#     entered_context = _TracerEnteredStackContext(context)
# 
#     if span is None:
#         return entered_context
# 
#     opentracing.tracer.scope_manager.activate(span, False)
#     assert opentracing.tracer.active_span is not None
#     assert opentracing.tracer.active_span is span
# 
#     return entered_context
# 
# class RequestContext(object):
#     """
#     DEPRECATED, use either span_in_context() or span_in_stack_context()
#     instead.
# 
#     RequestContext represents the context of a request being executed.
# 
#     Useful when a service needs to make downstream calls to other services
#     and requires access to some aspects of the original request, such as
#     tracing information.
# 
#     It is designed to hold a reference to the current OpenTracing Span,
#     but the class can be extended to store more information.
#     """
# 
#     __slots__ = ('span', )
# 
#     def __init__(self, span):
#         self.span = span
# 
# class RequestContextManager(object):
#     """
#     DEPRECATED, use either span_in_context() or span_in_stack_context()
#     instead.
# 
#     A context manager that saves RequestContext in thread-local state.
# 
#     Intended for use with ThreadSafeStackContext (a thread-safe
#     replacement for Tornado's StackContext) or as context manager
#     in a WSGI middleware.
#     """
# 
#     _state = threading.local()
#     _state.context = None
# 
#     @classmethod
#     def current_context(cls):
#         """Get the current request context.
# 
#         :rtype: opentracing_instrumentation.RequestContext
#         :returns: The current request context, or None.
#         """
#         return getattr(cls._state, 'context', None)
# 
#     def __init__(self, context=None, span=None):
#         # normally we want the context parameter, but for backwards
#         # compatibility we make it optional and allow span as well
#         if span:
#             self._context = RequestContext(span=span)
#         elif isinstance(context, opentracing.Span):
#             self._context = RequestContext(span=context)
#         else:
#             self._context = context
# 
#     def __enter__(self):
#         self._prev_context = self.__class__.current_context()
#         self.__class__._state.context = self._context
#         return self._context
# 
#     def __exit__(self, *_):
#         self.__class__._state.context = self._prev_context
#         self._prev_context = None
#         return False


# Path: tests/opentracing_instrumentation/test_tornado_request_context.py
import opentracing
from opentracing.scope_managers.tornado import TornadoScopeManager
from opentracing_instrumentation.request_context import (
    get_current_span,
    span_in_stack_context,
    RequestContext,
    RequestContextManager,
)
from mock import patch
from tornado import gen
from tornado import stack_context
from tornado.testing import AsyncTestCase, gen_test

        span1 = 'Bender is great!'
        span2 = 'Fry is dumb!'

        @gen.coroutine
        def check(span_to_check):
            assert get_current_span() == span_to_check

        with self.assertRaises(Exception):  # passing mismatching spans
            yield run_coroutine_with_span(span1, check, span2)

        @gen.coroutine
        def nested(nested_span_to_check, span_to_check):
            yield run_coroutine_with_span(span1, check, nested_span_to_check)
            assert get_current_span() == span_to_check

        with self.assertRaises(Exception):  # passing mismatching spans
            yield run_coroutine_with_span(span2, nested, span1, span1)
        with self.assertRaises(Exception):  # passing mismatching spans
            yield run_coroutine_with_span(span2, nested, span2, span2)

        # successful case
        yield run_coroutine_with_span(span2, nested, span1, span2)

    def test_no_span(self):
        ctx = RequestContextManager(context=RequestContext(span='x'))
        assert ctx._context.span == 'x'
        assert RequestContextManager.current_context() is None

    def test_backwards_compatible(self):
        span = opentracing.tracer.start_span(operation_name='test')

        mgr = RequestContextManager(span)  # span as positional arg