text: Title: Version 2.2.0 crashes when using app.test_client() as a context-manager in multi-threaded tests
  Body: The following code defines a simple app, and queries it from a test that uses threads:
  
  ```py
  import threading
  
  from flask import Flask
  import pytest
  
  
  def create_app():
      app = Flask(__name__)
  
      @app.route("/hi", methods=["POST"])
      def hello():
          return "Hello, World!"
  
      return app
  
  
  @pytest.fixture()
  def app():
      app = create_app()
      yield app
  
  
  @pytest.fixture()
  def client(app):
      with app.test_client() as client:
          yield client
  
  
  def test_request_example(client):
      successes = 0
  
      def f():
          nonlocal successes
          response = client.post("/hi")
          assert "Hello, World!" == response.text
          successes += 1
  
      thread = threading.Thread(target=f)
      thread.start()
      thread.join()
  
      f()
  
      assert successes == 2
  ```
  
  When running with pytest on Flask 2.1.3, this test passes:
  
  ```
  ========================================================================= test session starts ==========================================================================
  platform linux -- Python 3.9.2, pytest-7.1.2, pluggy-0.13.0
  rootdir: /home/dev/swh-environment/swh-indexer, configfile: pytest.ini
  plugins: asyncio-0.18.3, requests-mock-1.9.3, django-4.5.2, xdist-2.5.0, swh.core-2.13, mock-3.8.2, django-test-migrations-1.2.0, flask-1.2.0, redis-2.4.0, hypothesis-6.49.1, cov-3.0.0, subtesthack-0.1.2, forked-1.3.0, postgresql-3.1.3, swh.journal-0.8.1.dev3+gf92d4ac
  asyncio: mode=strict
  collected 1 item                                                                                                                                                       
  
  test_flask_threads.py .                                                                                                                                          [100%]
  
  ===================================================================== 1 passed, 1 warning in 0.02s =====================================================================
  ```
  
  However, when running with Flask 2.2.0:
  
  ```
  ========================================================================= test session starts ==========================================================================
  platform linux -- Python 3.9.2, pytest-7.1.2, pluggy-0.13.0
  rootdir: /home/dev/swh-environment/swh-indexer, configfile: pytest.ini
  plugins: asyncio-0.18.3, requests-mock-1.9.3, django-4.5.2, xdist-2.5.0, swh.core-2.13, mock-3.8.2, django-test-migrations-1.2.0, flask-1.2.0, redis-2.4.0, hypothesis-6.49.1, cov-3.0.0, subtesthack-0.1.2, forked-1.3.0, postgresql-3.1.3, swh.journal-0.8.1.dev3+gf92d4ac
  asyncio: mode=strict
  collected 1 item                                                                                                                                                       
  
  test_flask_threads.py F                                                                                                                                          [100%]
  
  =============================================================================== FAILURES ===============================================================================
  _________________________________________________________________________ test_request_example _________________________________________________________________________
  
  self = <contextlib.ExitStack object at 0x7fc444b63b20>
  exc_details = (<class 'ValueError'>, ValueError("<Token var=<ContextVar name='flask.request_ctx' at 0x7fc44844a1d0> at 0x7fc444a18a80> was created in a different Context"), <traceback object at 0x7fc444a18d40>)
  received_exc = False, _fix_exception_context = <function ExitStack.__exit__.<locals>._fix_exception_context at 0x7fc444a7edc0>, suppressed_exc = False
  
      def __exit__(self, *exc_details):
          received_exc = exc_details[0] is not None
      
          # We manipulate the exception state so it behaves as though
          # we were actually nesting multiple with statements
          frame_exc = sys.exc_info()[1]
          def _fix_exception_context(new_exc, old_exc):
              # Context may not be correct, so find the end of the chain
              while 1:
                  exc_context = new_exc.__context__
                  if exc_context is old_exc:
                      # Context is already set correctly (see issue 20317)
                      return
                  if exc_context is None or exc_context is frame_exc:
                      break
                  new_exc = exc_context
              # Change the end of the chain to point to the exception
              # we expect it to reference
              new_exc.__context__ = old_exc
      
          # Callbacks are invoked in LIFO order to match the behaviour of
          # nested context managers
          suppressed_exc = False
          pending_raise = False
          while self._exit_callbacks:
              is_sync, cb = self._exit_callbacks.pop()
              assert is_sync
              try:
  >               if cb(*exc_details):
  
  /usr/lib/python3.9/contextlib.py:498: 
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
  
  self = <flask.ctx.AppContext object at 0x7fc444b75730>, exc_type = None, exc_value = None, tb = None
  
      def __exit__(
          self,
          exc_type: t.Optional[type],
          exc_value: t.Optional[BaseException],
          tb: t.Optional[TracebackType],
      ) -> None:
  >       self.pop(exc_value)
  
  ../../.local/lib/python3.9/site-packages/flask/ctx.py:275: 
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
  
  self = <flask.ctx.AppContext object at 0x7fc444b75730>, exc = None
  
      def pop(self, exc: t.Optional[BaseException] = _sentinel) -> None:  # type: ignore
          """Pops the app context."""
          try:
              if len(self._cv_tokens) == 1:
                  if exc is _sentinel:
                      exc = sys.exc_info()[1]
                  self.app.do_teardown_appcontext(exc)
          finally:
              ctx = _cv_app.get()
  >           _cv_app.reset(self._cv_tokens.pop())
  E           ValueError: <Token var=<ContextVar name='flask.app_ctx' at 0x7fc44844f090> at 0x7fc444a18ac0> was created in a different Context
  
  ../../.local/lib/python3.9/site-packages/flask/ctx.py:256: ValueError
  
  During handling of the above exception, another exception occurred:
  
  client = <FlaskClient <Flask 'test_flask_threads'>>
  
      def test_request_example(client):
          successes = 0
      
          def f():
              nonlocal successes
              response = client.post("/hi")
              assert "Hello, World!" == response.text
              successes += 1
      
          thread = threading.Thread(target=f)
          thread.start()
          thread.join()
      
  >       f()
  
  test_flask_threads.py:42: 
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
  test_flask_threads.py:34: in f
      response = client.post("/hi")
  ../../.local/lib/python3.9/site-packages/werkzeug/test.py:1140: in post
      return self.open(*args, **kw)
  ../../.local/lib/python3.9/site-packages/flask/testing.py:221: in open
      self._context_stack.close()
  /usr/lib/python3.9/contextlib.py:521: in close
      self.__exit__(None, None, None)
  /usr/lib/python3.9/contextlib.py:513: in __exit__
      raise exc_details[1]
  /usr/lib/python3.9/contextlib.py:498: in __exit__
      if cb(*exc_details):
  ../../.local/lib/python3.9/site-packages/flask/ctx.py:432: in __exit__
      self.pop(exc_value)
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
  
  self = <RequestContext 'http://localhost/hi' [POST] of test_flask_threads>
  exc = ValueError("<Token var=<ContextVar name='flask.app_ctx' at 0x7fc44844f090> at 0x7fc444a18ac0> was created in a different Context")
  
      def pop(self, exc: t.Optional[BaseException] = _sentinel) -> None:  # type: ignore
          """Pops the request context and unbinds it by doing that.  This will
          also trigger the execution of functions registered by the
          :meth:`~flask.Flask.teardown_request` decorator.
      
          .. versionchanged:: 0.9
             Added the `exc` argument.
          """
          clear_request = len(self._cv_tokens) == 1
      
          try:
              if clear_request:
                  if exc is _sentinel:
                      exc = sys.exc_info()[1]
                  self.app.do_teardown_request(exc)
      
                  request_close = getattr(self.request, "close", None)
                  if request_close is not None:
                      request_close()
          finally:
              ctx = _cv_request.get()
              token, app_ctx = self._cv_tokens.pop()
  >           _cv_request.reset(token)
  E           ValueError: <Token var=<ContextVar name='flask.request_ctx' at 0x7fc44844a1d0> at 0x7fc444a18a80> was created in a different Context
  
  ../../.local/lib/python3.9/site-packages/flask/ctx.py:407: ValueError
  ======================================================================= short test summary info ========================================================================
  FAILED test_flask_threads.py::test_request_example - ValueError: <Token var=<ContextVar name='flask.request_ctx' at 0x7fc44844a1d0> at 0x7fc444a18a80> was created in...
  ===================================================================== 1 failed, 1 warning in 0.11s =====================================================================
  ```
  
  Environment:
  
  - Python version: 3.9
  - Flask version: 2.2.0
  