Skip to content

Conversation

gpauloski
Copy link
Contributor

Summary

I think it's time to enable CI testing on MacOS since that's commonly used for development. I hadn't enabled it initially when we were moving fast with development, but fortunately it works okay.

Related Issues

N/A

Changes

  • Breaking (backwards incompatible changes to public interfaces)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (non-breaking change or feature addition)
  • Refactor (internal code or design clean up)
  • Documentation (no changes to the code)
  • Test (changes or additions to testing)
  • Build (change to CI workflows or build processes)
  • Package (changes to package metadata or dependency versions)

Testing

N/A

Pull Request Checklist

Please confirm the PR meets the following requirements.

  • Relevant tags are added based on the types of changes.
  • Code changes pass pre-commit (e.g., ruff, mypy, etc.).
  • Tests have been added to show the fix is effective or that the new feature works.
  • New and existing unit tests pass locally with the changes.
  • Docs have been updated and reviewed if relevant.

@gpauloski gpauloski added the test Adds or changes tests label Sep 27, 2025
@gpauloski gpauloski force-pushed the gpauloski-macos-testing branch from 655a974 to 3967bd2 Compare September 27, 2025 18:58
@gpauloski
Copy link
Contributor Author

I think the hangs in the unit tests are related to #213. Odd that it hangs rather than crashing like on linux though.

I occasionally observe the hang locally and interrupting the process produced this stack trace:

$ tox -e py313
.pkg: _optional_hooks> python /Users/jgpaul/workspace/academy/venv/lib/python3.13/site-packages/pyproject_api/_backend.py True setuptools.build_meta
.pkg: get_requires_for_build_sdist> python /Users/jgpaul/workspace/academy/venv/lib/python3.13/site-packages/pyproject_api/_backend.py True setuptools.build_meta
.pkg: build_sdist> python /Users/jgpaul/workspace/academy/venv/lib/python3.13/site-packages/pyproject_api/_backend.py True setuptools.build_meta
py313: install_package> python -I -m pip install --force-reinstall --no-deps /Users/jgpaul/workspace/academy/.tox/.tmp/package/84/academy_py-0.3.0.tar.gz
py313: commands[0]> coverage erase
py313: commands[1]> coverage run -m pytest tests/unit
============================================ test session starts =============================================
platform darwin -- Python 3.13.0, pytest-8.4.2, pluggy-1.6.0
cachedir: .tox/py313/.pytest_cache
rootdir: /Users/jgpaul/workspace/academy
configfile: pyproject.toml
plugins: asyncio-1.2.0, cov-7.0.0
asyncio: mode=Mode.AUTO, debug=False, asyncio_default_fixture_loop_scope=function, asyncio_default_test_loop_scope=function
collected 342 items

tests/unit/agent_test.py .................                                                             [  4%]
tests/unit/context_test.py ..                                                                          [  5%]
tests/unit/event_test.py .....                                                                         [  7%]
tests/unit/exchange/client_test.py .................................................F^CROOT: [74549] KeyboardInterrupt - teardown started
ROOT: interrupt tox environment: py313
ROOT: requested interrupt of 74577 from 74549, activate in 0.00
ROOT: send signal SIGINT(2) to 74577 from 74549 with timeout 0.30


================================================== FAILURES ==================================================
_________________________ test_client_reply_error_on_request[GlobusExchangeFactory] __________________________

factory = <academy.exchange.cloud.globus.GlobusExchangeFactory object at 0x1060cf890>

    @pytest.mark.asyncio
    async def test_client_reply_error_on_request(
        factory: ExchangeFactory[Any],
    ) -> None:
        async with await factory.create_user_client(
            start_listener=False,
        ) as client1:
>           async with await factory.create_user_client(
                start_listener=True,
            ) as client2:

tests/unit/exchange/client_test.py:218:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
academy/exchange/client.py:88: in __aexit__
    await self.close()
academy/exchange/client.py:325: in close
    await self._transport.terminate(self.client_id)
academy/exchange/cloud/globus.py:549: in terminate
    await loop.run_in_executor(
/opt/homebrew/Cellar/[email protected]/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/concurrent/futures/thread.py:58: in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
academy/exchange/cloud/globus.py:545: in _terminate
    self.exchange_client.terminate(uid)
academy/exchange/cloud/globus.py:149: in terminate
    return self.request(
.tox/py313/lib/python3.13/site-packages/globus_sdk/client.py:498: in request
    authorizer = self._app.get_authorizer(self.resource_server)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.tox/py313/lib/python3.13/site-packages/globus_sdk/globus_app/app.py:442: in get_authorizer
    return self._authorizer_factory.get_authorizer(resource_server)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.tox/py313/lib/python3.13/site-packages/globus_sdk/globus_app/authorizer_factory.py:90: in get_authorizer
    new_authorizer = self._make_authorizer(resource_server)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.tox/py313/lib/python3.13/site-packages/globus_sdk/globus_app/authorizer_factory.py:268: in _make_authorizer
    return ClientCredentialsAuthorizer(
.tox/py313/lib/python3.13/site-packages/globus_sdk/authorizers/client_credentials.py:78: in __init__
    super().__init__(access_token, expires_at, on_refresh)
.tox/py313/lib/python3.13/site-packages/globus_sdk/authorizers/renewing.py:90: in __init__
    self._get_new_access_token()
.tox/py313/lib/python3.13/site-packages/globus_sdk/authorizers/renewing.py:138: in _get_new_access_token
    self.on_refresh(res)
.tox/py313/lib/python3.13/site-packages/globus_sdk/tokenstorage/v2/base.py:97: in store_token_response
    self.store_token_data_by_resource_server(token_data_by_resource_server)
.tox/py313/lib/python3.13/site-packages/globus_sdk/tokenstorage/v2/validating_token_storage/storage.py:76: in store_token_data_by_resource_server
    self.token_storage.store_token_data_by_resource_server(
.tox/py313/lib/python3.13/site-packages/globus_sdk/tokenstorage/v2/json.py:139: in store_token_data_by_resource_server
    to_write = self._load()
               ^^^^^^^^^^^^
.tox/py313/lib/python3.13/site-packages/globus_sdk/tokenstorage/v2/json.py:114: in _load
    data = self._raw_load()
           ^^^^^^^^^^^^^^^^
.tox/py313/lib/python3.13/site-packages/globus_sdk/tokenstorage/v2/json.py:54: in _raw_load
    val = json.load(f)
          ^^^^^^^^^^^^
/opt/homebrew/Cellar/[email protected]/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/json/__init__.py:293: in load
    return loads(fp.read(),
/opt/homebrew/Cellar/[email protected]/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/json/__init__.py:346: in loads
    return _default_decoder.decode(s)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
/opt/homebrew/Cellar/[email protected]/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/json/decoder.py:344: in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <json.decoder.JSONDecoder object at 0x1011b7b60>, s = '', idx = 0

    def raw_decode(self, s, idx=0):
        """Decode a JSON document from ``s`` (a ``str`` beginning with
        a JSON document) and return a 2-tuple of the Python
        representation and the index in ``s`` where the document ended.

        This can be used to decode a JSON document from a string that may
        have extraneous data at the end.

        """
        try:
            obj, end = self.scan_once(s, idx)
        except StopIteration as err:
>           raise JSONDecodeError("Expecting value", s, err.value) from None
E           json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

/opt/homebrew/Cellar/[email protected]/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/json/decoder.py:362: JSONDecodeError
--------------------------------------------- Captured log call ----------------------------------------------
WARNING  globus_sdk.response:response.py:80 response data did not parse as JSON, data=None
WARNING  globus_sdk.response:response.py:80 response data did not parse as JSON, data=None
WARNING  globus_sdk.response:response.py:80 response data did not parse as JSON, data=None
WARNING  globus_sdk.response:response.py:80 response data did not parse as JSON, data=None
WARNING  academy.exchange.client:client.py:337 Exchange client for UserId<e99cd9a7> received unexpected request message from UserId<44bfcbb1>
WARNING  globus_sdk.response:response.py:80 response data did not parse as JSON, data=None
========================================== short test summary info ===========================================
FAILED tests/unit/exchange/client_test.py::test_client_reply_error_on_request[GlobusExchangeFactory] - json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
================================== 1 failed, 73 passed in 80.18s (0:01:20) ===================================
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/[email protected]/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/base_events.py", line 721, in run_until_complete
    return future.result()
           ~~~~~~~~~~~~~^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pytest_asyncio/plugin.py", line 327, in async_finalizer
    await gen_obj.__anext__()
  File "/Users/jgpaul/workspace/academy/testing/fixture.py", line 168, in http_exchange_server
    await runner.cleanup()
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/aiohttp/web_runner.py", line 309, in cleanup
    await self._server.shutdown(self._shutdown_timeout)
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/aiohttp/web_server.py", line 71, in shutdown
    await asyncio.gather(*coros)
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/aiohttp/web_protocol.py", line 323, in shutdown
    await asyncio.shield(self._task_handler)
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/main.py", line 289, in wrap_session
    session.exitstatus = doit(config, session) or 0
                         ~~~~^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/main.py", line 343, in _main
    config.hook.pytest_runtestloop(session=session)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_hooks.py", line 512, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 167, in _multicall
    raise exception
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/logging.py", line 801, in pytest_runtestloop
    return (yield)  # Run all the tests.
            ^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/terminal.py", line 688, in pytest_runtestloop
    result = yield
             ^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 121, in _multicall
    res = hook_impl.function(*args)
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/main.py", line 367, in pytest_runtestloop
    item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_hooks.py", line 512, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 167, in _multicall
    raise exception
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/warnings.py", line 90, in pytest_runtest_protocol
    return (yield)
            ^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/assertion/__init__.py", line 192, in pytest_runtest_protocol
    return (yield)
            ^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/unittest.py", line 475, in pytest_runtest_protocol
    return (yield)
            ^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/faulthandler.py", line 88, in pytest_runtest_protocol
    return (yield)
            ^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 121, in _multicall
    res = hook_impl.function(*args)
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/runner.py", line 117, in pytest_runtest_protocol
    runtestprotocol(item, nextitem=nextitem)
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/runner.py", line 141, in runtestprotocol
    reports.append(call_and_report(item, "teardown", log, nextitem=nextitem))
                   ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/runner.py", line 245, in call_and_report
    call = CallInfo.from_call(
        lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
    )
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/runner.py", line 344, in from_call
    result: TResult | None = func()
                             ~~~~^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/runner.py", line 246, in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
            ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_hooks.py", line 512, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 167, in _multicall
    raise exception
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/logging.py", line 858, in pytest_runtest_teardown
    yield
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/capture.py", line 905, in pytest_runtest_teardown
    return (yield)
            ^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 121, in _multicall
    res = hook_impl.function(*args)
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/runner.py", line 193, in pytest_runtest_teardown
    item.session._setupstate.teardown_exact(nextitem)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/runner.py", line 546, in teardown_exact
    fin()
    ~~~^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/fixtures.py", line 1069, in finish
    raise exceptions[0]
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/fixtures.py", line 1058, in finish
    fin()
    ~~~^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pytest_asyncio/plugin.py", line 335, in finalizer
    runner.run(async_finalizer(), context=context)
    ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/runners.py", line 123, in run
    raise KeyboardInterrupt()
KeyboardInterrupt

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/jgpaul/workspace/academy/.tox/py313/bin/coverage", line 7, in <module>
    sys.exit(main())
             ~~~~^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/coverage/cmdline.py", line 1135, in main
    status = CoverageScript().command_line(argv)
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/coverage/cmdline.py", line 834, in command_line
    return self.do_run(options, args)
           ~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/coverage/cmdline.py", line 1023, in do_run
    runner.run()
    ~~~~~~~~~~^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/coverage/execfile.py", line 213, in run
    exec(code, main_mod.__dict__)
    ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pytest/__main__.py", line 9, in <module>
    raise SystemExit(pytest.console_main())
                     ~~~~~~~~~~~~~~~~~~~^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/config/__init__.py", line 201, in console_main
    code = main()
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/config/__init__.py", line 175, in main
    ret: ExitCode | int = config.hook.pytest_cmdline_main(config=config)
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_hooks.py", line 512, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 167, in _multicall
    raise exception
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 121, in _multicall
    res = hook_impl.function(*args)
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/main.py", line 336, in pytest_cmdline_main
    return wrap_session(config, _main)
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/main.py", line 303, in wrap_session
    config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_hooks.py", line 512, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 167, in _multicall
    raise exception
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/pluggy/_callers.py", line 121, in _multicall
    res = hook_impl.function(*args)
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/terminal.py", line 975, in pytest_keyboard_interrupt
    self._keyboardinterrupt_memo = excinfo.getrepr(funcargs=True)
                                   ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/_code/code.py", line 766, in getrepr
    return fmt.repr_excinfo(self)
           ~~~~~~~~~~~~~~~~^^^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/_code/code.py", line 1202, in repr_excinfo
    reprtraceback = self.repr_traceback(excinfo_)
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/_code/code.py", line 1129, in repr_traceback
    last = traceback[-1]
           ~~~~~~~~~^^^^
  File "/Users/jgpaul/workspace/academy/.tox/py313/lib/python3.13/site-packages/_pytest/_code/code.py", line 418, in __getitem__
    def __getitem__(self, key: SupportsIndex | slice) -> TracebackEntry | Traceback:

KeyboardInterrupt
ROOT: send signal SIGTERM(15) to 74577 from 74549 with timeout 0.20
ROOT: interrupt finished with success
py313: exit -15 (81.04 seconds) /Users/jgpaul/workspace/academy> coverage run -m pytest tests/unit pid=74577
.pkg: interrupt tox environment: .pkg
  py313: FAIL code -15 (83.68=setup[2.57]+cmd[0.08,81.04] seconds)
  evaluation failed :( (83.72 seconds)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
test Adds or changes tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant