Skip to content

Conversation

alexander-alderman-webb
Copy link
Contributor

@alexander-alderman-webb alexander-alderman-webb commented Sep 5, 2025

Automatically fork isolation and current scopes when running tasks with concurrent.future. The implementation is essentially packaging work-around #4508 (comment) as an integration.

The tests are adapted from test_threading.py, but only use ThreadPoolExecutor.

Closes #4565

Copy link

codecov bot commented Sep 5, 2025

❌ 9 Tests Failed:

Tests completed Failed Passed Skipped
23676 9 23667 2305
View the top 3 failed test(s) by shortest run time
tests.integrations.requests.test_requests::test_crumb_capture
Stack Traces | 0.141s run time
+ Exception Group Traceback (most recent call last):
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9....../site-packages/_pytest/runner.py", line 344, in from_call
  |     result: TResult | None = func()
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9....../site-packages/_pytest/runner.py", line 246, in <lambda>
  |     lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9.../site-packages/pluggy/_hooks.py", line 512, in __call__
  |     return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9.../site-packages/pluggy/_manager.py", line 120, in _hookexec
  |     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9......................../site-packages/pluggy/_callers.py", line 167, in _multicall
  |     raise exception
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9......................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9.../site-packages/_pytest/logging.py", line 850, in pytest_runtest_call
  |     yield
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9......................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9......................../site-packages/pluggy/_callers.py", line 53, in run_old_style_hookwrapper
  |     return result.get_result()
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9.../site-packages/pluggy/_result.py", line 103, in get_result
  |     raise exc.with_traceback(tb)
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9......................../site-packages/pluggy/_callers.py", line 38, in run_old_style_hookwrapper
  |     res = yield
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9......................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9.../site-packages/_pytest/capture.py", line 900, in pytest_runtest_call
  |     return (yield)
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9......................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9.../site-packages/_pytest/skipping.py", line 263, in pytest_runtest_call
  |     return (yield)
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9......................../site-packages/pluggy/_callers.py", line 121, in _multicall
  |     res = hook_impl.function(*args)
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9............/site-packages/_pytest/unraisableexception.py", line 158, in pytest_runtest_call
  |     collect_unraisable(item.config)
  |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9............/site-packages/_pytest/unraisableexception.py", line 81, in collect_unraisable
  |     raise ExceptionGroup("multiple unraisable exception warnings", errors)
  | exceptiongroup.ExceptionGroup: multiple unraisable exception warnings (2 sub-exceptions)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "<string>", line 1, in <lambda>
    | KeyError: '__import__'
    | 
    | The above exception was the direct cause of the following exception:
    | 
    | Traceback (most recent call last):
    |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9............/site-packages/_pytest/unraisableexception.py", line 67, in collect_unraisable
    |     warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))
    | pytest.PytestUnraisableExceptionWarning: Exception ignored in: <coroutine object patch_asyncio.<locals>._sentry_task_factory.<locals>._task_with_sentry_span_creation at 0x7fee34bc61c0>
    | Enable tracemalloc to get traceback where the object was allocated.
    | See https://docs.pytest..../stable/how-to/capture-warnings.html#resource-warnings for more info.
    +---------------- 2 ----------------
    | Traceback (most recent call last):
    |   File "<string>", line 1, in <lambda>
    | KeyError: '__import__'
    | 
    | The above exception was the direct cause of the following exception:
    | 
    | Traceback (most recent call last):
    |   File ".../sentry-python/sentry-python/.tox/py3.9-common/lib/python3.9............/site-packages/_pytest/unraisableexception.py", line 67, in collect_unraisable
    |     warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))
    | pytest.PytestUnraisableExceptionWarning: Exception ignored in: <coroutine object patch_asyncio.<locals>._sentry_task_factory.<locals>._task_with_sentry_span_creation at 0x7fee34bc61c0>
    | Enable tracemalloc to get traceback where the object was allocated.
    | See https://docs.pytest..../stable/how-to/capture-warnings.html#resource-warnings for more info.
    +------------------------------------
tests.integrations.django.asgi.test_asgi::test_asgi_request_body[False-POST-headers6-post_echo_async-some raw text body--application0]
Stack Traces | 0.233s run time
.../django/asgi/test_asgi.py:573: in test_asgi_request_body
    assert event["request"]["data"] == expected_data
E   KeyError: 'data'
tests.integrations.django.asgi.test_asgi::test_asgi_request_body[False-POST-headers9-post_echo_async---fd721ef49ea403a6\r\nContent-Disposition: form-data; name="username"\r\n\r\nJane\r\n--fd721ef49ea403a6\r\nContent-Disposition: form-data; name="password"\r\n\r\nhello123\r\n--fd721ef49ea403a6\r\nContent-Disposition: form-data; name="photo"; filename="image.png"\r\nContent-Type: image/png\r\nContent-Transfer-Encoding: base64\r\n\r\niVBORw0KGgoAAAANSUhEUgAAAAoAAAAJCAYAAAALpr0TAAAA+0lEQVQYV2P8DwQMSKCvcxGYV1QehyzMwIiscMvGgwzPn74GK5CUFmXw8beHK0ZR6O+exzB9Xi0DLy8XQ2ZSM4TNxw1WDFf4DGjS82evGfqBVte1ZDLcuvkAbHpqVghCIUgRyAQjU02GyBgvBpA7uycWMZTm9wE1ZTBIAZ0BNhEkAbIO5K5bNx4yqGnIg00zMtViWLFkO1BTMQPjzesP/ktKiTA01c5gSM0MAZsGMqWpZgbDjPm1DI0108GeYowOLv8PcvTnz98YZk9fw2AMNAUEDu47w1DXnAFmg5zFmJ7Q9J+RERIKoBBNzQpmaAaaDgK1QIWgIPsCNAQAgad47ThM9dkAAAAASUVORK5CYII=\r\n--fd721ef49ea403a6--\r\n-expected_data9-application0]
Stack Traces | 0.233s run time
.../django/asgi/test_asgi.py:573: in test_asgi_request_body
    assert event["request"]["data"] == expected_data
E   KeyError: 'data'
tests.integrations.django.asgi.test_asgi::test_asgi_request_body[True-POST-headers3-post_echo_async-<?xml version="1.0" encoding="UTF-8"?><root></root>--application0]
Stack Traces | 0.233s run time
.../django/asgi/test_asgi.py:573: in test_asgi_request_body
    assert event["request"]["data"] == expected_data
E   KeyError: 'data'
tests.integrations.django.asgi.test_asgi::test_asgi_request_body[True-POST-headers4-post_echo_async---fd721ef49ea403a6\r\nContent-Disposition: form-data; name="username"\r\n\r\nJane\r\n--fd721ef49ea403a6\r\nContent-Disposition: form-data; name="password"\r\n\r\nhello123\r\n--fd721ef49ea403a6\r\nContent-Disposition: form-data; name="photo"; filename="image.png"\r\nContent-Type: image/png\r\nContent-Transfer-Encoding: base64\r\n\r\niVBORw0KGgoAAAANSUhEUgAAAAoAAAAJCAYAAAALpr0TAAAA+0lEQVQYV2P8DwQMSKCvcxGYV1QehyzMwIiscMvGgwzPn74GK5CUFmXw8beHK0ZR6O+exzB9Xi0DLy8XQ2ZSM4TNxw1WDFf4DGjS82evGfqBVte1ZDLcuvkAbHpqVghCIUgRyAQjU02GyBgvBpA7uycWMZTm9wE1ZTBIAZ0BNhEkAbIO5K5bNx4yqGnIg00zMtViWLFkO1BTMQPjzesP/ktKiTA01c5gSM0MAZsGMqWpZgbDjPm1DI0108GeYowOLv8PcvTnz98YZk9fw2AMNAUEDu47w1DXnAFmg5zFmJ7Q9J+RERIKoBBNzQpmaAaaDgK1QIWgIPsCNAQAgad47ThM9dkAAAAASUVORK5CYII=\r\n--fd721ef49ea403a6--\r\n-expected_data4-application0]
Stack Traces | 0.233s run time
.../django/asgi/test_asgi.py:573: in test_asgi_request_body
    assert event["request"]["data"] == expected_data
E   KeyError: 'data'
tests.integrations.django.asgi.test_asgi::test_asgi_request_body[False-POST-headers7-post_echo_async-{"username":"xyz","password":"xyz"}-expected_data7-application0]
Stack Traces | 0.234s run time
.../django/asgi/test_asgi.py:573: in test_asgi_request_body
    assert event["request"]["data"] == expected_data
E   KeyError: 'data'
tests.integrations.django.asgi.test_asgi::test_asgi_request_body[False-POST-headers8-post_echo_async-<?xml version="1.0" encoding="UTF-8"?><root></root>--application0]
Stack Traces | 0.234s run time
.../django/asgi/test_asgi.py:573: in test_asgi_request_body
    assert event["request"]["data"] == expected_data
E   KeyError: 'data'
tests.integrations.django.asgi.test_asgi::test_asgi_request_body[True-POST-headers2-post_echo_async-{"username":"xyz","password":"xyz"}-expected_data2-application0]
Stack Traces | 0.234s run time
.../django/asgi/test_asgi.py:573: in test_asgi_request_body
    assert event["request"]["data"] == expected_data
E   KeyError: 'data'
tests.integrations.django.asgi.test_asgi::test_asgi_request_body[True-POST-headers1-post_echo_async-some raw text body--application0]
Stack Traces | 0.235s run time
.../django/asgi/test_asgi.py:573: in test_asgi_request_body
    assert event["request"]["data"] == expected_data
E   KeyError: 'data'
tests.integrations.django.asgi.test_asgi::test_async_views[application0]
Stack Traces | 0.236s run time
.../django/asgi/test_asgi.py:110: in test_async_views
    assert event["request"] == {
E   AssertionError: assert {'headers': {}, 'method': 'GET', 'query_string': None, 'url': '/async_message'} == {'cookies': {},\n 'headers': {},\n 'method': 'GET',\n 'query_string': None,\n 'url': '/async_message'}
E     Common items:
E     {'headers': {}, 'method': 'GET', 'query_string': None, 'url': '/async_message'}
E     Right contains 1 more item:
E     {'cookies': {}}
E     Full diff:
E       {
E     -  'cookies': {},
E        'headers': {},
E        'method': 'GET',
E        'query_string': None,
E        'url': '/async_message',
E       }

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@antonpirker antonpirker added the New Integration Integrating with a new framework or library label Sep 11, 2025
@alexander-alderman-webb alexander-alderman-webb marked this pull request as ready for review September 25, 2025 10:02
@alexander-alderman-webb alexander-alderman-webb requested a review from a team as a code owner September 25, 2025 10:02
cursor[bot]

This comment was marked as outdated.

@alexander-alderman-webb alexander-alderman-webb marked this pull request as draft September 25, 2025 13:54
cursor[bot]

This comment was marked as outdated.

@alexander-alderman-webb alexander-alderman-webb marked this pull request as ready for review September 25, 2025 14:00
cursor[bot]

This comment was marked as outdated.

@alexander-alderman-webb alexander-alderman-webb marked this pull request as draft September 25, 2025 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
New Integration Integrating with a new framework or library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support ThreadPoolExecutor with a concurrency integration
2 participants