
self = <austin.format.mojo.MojoStreamReader object at 0x000001D9AADE2390>

    def parse_event(self) -> t.Optional[MojoEvent]:
        """Parse a single event."""
        try:
            (event_id,) = self.read()
        except ValueError:
            return None
    
        try:
>           event = t.cast(dict, self.__handlers__)[event_id](self)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E           KeyError: 13

venv\Lib\site-packages\austin\format\mojo.py:622: KeyError

The above exception was the direct cause of the following exception:

cls = <class '_pytest.runner.CallInfo'>
func = <function FlakyPlugin.call_and_report.<locals>._call_runtest_hook.<locals>.<lambda> at 0x000001D9AAE4ADE0>
when = 'call'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    @classmethod
    def from_call(
        cls,
        func: Callable[[], TResult],
        when: Literal["collect", "setup", "call", "teardown"],
        reraise: type[BaseException] | tuple[type[BaseException], ...] | None = None,
    ) -> CallInfo[TResult]:
        """Call func, wrapping the result in a CallInfo.
    
        :param func:
            The function to call. Called without arguments.
        :type func: Callable[[], _pytest.runner.TResult]
        :param when:
            The phase in which the function is called.
        :param reraise:
            Exception or exceptions that shall propagate if raised by the
            function, instead of being wrapped in the CallInfo.
        """
        excinfo = None
        instant = timing.Instant()
        try:
>           result: TResult | None = func()
                                     ^^^^^^

venv\Lib\site-packages\_pytest\runner.py:353: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

>       lambda: ihook(item=item, **kwds), when=when, reraise=reraise
                ^^^^^^^^^^^^^^^^^^^^^^^^
    )

venv\Lib\site-packages\flaky\flaky_pytest_plugin.py:146: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <HookCaller 'pytest_runtest_call'>
kwargs = {'item': <Function test_attach_exposure[3.11-1]>}, firstresult = False

    def __call__(self, **kwargs: object) -> Any:
        """Call the hook.
    
        Only accepts keyword arguments, which should match the hook
        specification.
    
        Returns the result(s) of calling all registered plugins, see
        :ref:`calling`.
        """
        assert not self.is_historic(), (
            "Cannot directly call a historic hook - use call_historic instead."
        )
        self._verify_all_args_are_provided(kwargs)
        firstresult = self.spec.opts.get("firstresult", False) if self.spec else False
        # Copy because plugins may register other plugins during iteration (#438).
>       return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

venv\Lib\site-packages\pluggy\_hooks.py:512: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <_pytest.config.PytestPluginManager object at 0x000001D9A7D23C80>
hook_name = 'pytest_runtest_call'
methods = [<HookImpl plugin_name='threadexception', plugin=<module '_pytest.threadexception' from 'D:\\a\\austin\\austin\\venv\\...e=None>>, <HookImpl plugin_name='logging-plugin', plugin=<_pytest.logging.LoggingPlugin object at 0x000001D9A9159580>>]
kwargs = {'item': <Function test_attach_exposure[3.11-1]>}, firstresult = False

    def _hookexec(
        self,
        hook_name: str,
        methods: Sequence[HookImpl],
        kwargs: Mapping[str, object],
        firstresult: bool,
    ) -> object | list[object]:
        # called from all hookcaller instances.
        # enable_tracing will set its own wrapping function at self._inner_hookexec
>       return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

venv\Lib\site-packages\pluggy\_manager.py:120: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

hook_name = 'pytest_runtest_call'
hook_impls = [<HookImpl plugin_name='threadexception', plugin=<module '_pytest.threadexception' from 'D:\\a\\austin\\austin\\venv\\...e=None>>, <HookImpl plugin_name='logging-plugin', plugin=<_pytest.logging.LoggingPlugin object at 0x000001D9A9159580>>]
caller_kwargs = {'item': <Function test_attach_exposure[3.11-1]>}
firstresult = False

    def _multicall(
        hook_name: str,
        hook_impls: Sequence[HookImpl],
        caller_kwargs: Mapping[str, object],
        firstresult: bool,
    ) -> object | list[object]:
        """Execute a call into multiple python functions/methods and return the
        result(s).
    
        ``caller_kwargs`` comes from HookCaller.__call__().
        """
        __tracebackhide__ = True
        results: list[object] = []
        exception = None
        try:  # run impl and wrapper setup functions in a loop
            teardowns: list[Teardown] = []
            try:
                for hook_impl in reversed(hook_impls):
                    try:
                        args = [caller_kwargs[argname] for argname in hook_impl.argnames]
                    except KeyError as e:
                        # coverage bug - this is tested
                        for argname in hook_impl.argnames:  # pragma: no cover
                            if argname not in caller_kwargs:
                                raise HookCallError(
                                    f"hook call must provide argument {argname!r}"
                                ) from e
    
                    if hook_impl.hookwrapper:
                        function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args)
    
                        next(function_gen)  # first yield
                        teardowns.append(function_gen)
    
                    elif hook_impl.wrapper:
                        try:
                            # If this cast is not valid, a type error is raised below,
                            # which is the desired response.
                            res = hook_impl.function(*args)
                            function_gen = cast(Generator[None, object, object], res)
                            next(function_gen)  # first yield
                            teardowns.append(function_gen)
                        except StopIteration:
                            _raise_wrapfail(function_gen, "did not yield")
                    else:
                        res = hook_impl.function(*args)
                        if res is not None:
                            results.append(res)
                            if firstresult:  # halt further impl calls
                                break
            except BaseException as exc:
                exception = exc
        finally:
            if firstresult:  # first result hooks return a single value
                result = results[0] if results else None
            else:
                result = results
    
            # run all wrapper post-yield blocks
            for teardown in reversed(teardowns):
                try:
                    if exception is not None:
                        try:
                            teardown.throw(exception)
                        except RuntimeError as re:
                            # StopIteration from generator causes RuntimeError
                            # even for coroutine usage - see #544
                            if (
                                isinstance(exception, StopIteration)
                                and re.__cause__ is exception
                            ):
                                teardown.close()
                                continue
                            else:
                                raise
                    else:
                        teardown.send(result)
                    # Following is unreachable for a well behaved hook wrapper.
                    # Try to force finalizers otherwise postponed till GC action.
                    # Note: close() may raise if generator handles GeneratorExit.
                    teardown.close()
                except StopIteration as si:
                    result = si.value
                    exception = None
                    continue
                except BaseException as e:
                    exception = e
                    continue
                _raise_wrapfail(teardown, "has second yield")
    
        if exception is not None:
>           raise exception

venv\Lib\site-packages\pluggy\_callers.py:167: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

hook_name = 'pytest_runtest_call'
hook_impls = [<HookImpl plugin_name='threadexception', plugin=<module '_pytest.threadexception' from 'D:\\a\\austin\\austin\\venv\\...e=None>>, <HookImpl plugin_name='logging-plugin', plugin=<_pytest.logging.LoggingPlugin object at 0x000001D9A9159580>>]
caller_kwargs = {'item': <Function test_attach_exposure[3.11-1]>}
firstresult = False

    def _multicall(
        hook_name: str,
        hook_impls: Sequence[HookImpl],
        caller_kwargs: Mapping[str, object],
        firstresult: bool,
    ) -> object | list[object]:
        """Execute a call into multiple python functions/methods and return the
        result(s).
    
        ``caller_kwargs`` comes from HookCaller.__call__().
        """
        __tracebackhide__ = True
        results: list[object] = []
        exception = None
        try:  # run impl and wrapper setup functions in a loop
            teardowns: list[Teardown] = []
            try:
                for hook_impl in reversed(hook_impls):
                    try:
                        args = [caller_kwargs[argname] for argname in hook_impl.argnames]
                    except KeyError as e:
                        # coverage bug - this is tested
                        for argname in hook_impl.argnames:  # pragma: no cover
                            if argname not in caller_kwargs:
                                raise HookCallError(
                                    f"hook call must provide argument {argname!r}"
                                ) from e
    
                    if hook_impl.hookwrapper:
                        function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args)
    
                        next(function_gen)  # first yield
                        teardowns.append(function_gen)
    
                    elif hook_impl.wrapper:
                        try:
                            # If this cast is not valid, a type error is raised below,
                            # which is the desired response.
                            res = hook_impl.function(*args)
                            function_gen = cast(Generator[None, object, object], res)
                            next(function_gen)  # first yield
                            teardowns.append(function_gen)
                        except StopIteration:
                            _raise_wrapfail(function_gen, "did not yield")
                    else:
                        res = hook_impl.function(*args)
                        if res is not None:
                            results.append(res)
                            if firstresult:  # halt further impl calls
                                break
            except BaseException as exc:
                exception = exc
        finally:
            if firstresult:  # first result hooks return a single value
                result = results[0] if results else None
            else:
                result = results
    
            # run all wrapper post-yield blocks
            for teardown in reversed(teardowns):
                try:
                    if exception is not None:
                        try:
>                           teardown.throw(exception)

venv\Lib\site-packages\pluggy\_callers.py:139: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <_pytest.logging.LoggingPlugin object at 0x000001D9A9159580>
item = <Function test_attach_exposure[3.11-1]>

    @hookimpl(wrapper=True)
    def pytest_runtest_call(self, item: nodes.Item) -> Generator[None]:
        self.log_cli_handler.set_when("call")
    
        with self._runtest_for(item, "call"):
>           yield

venv\Lib\site-packages\_pytest\logging.py:850: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

hook_name = 'pytest_runtest_call'
hook_impls = [<HookImpl plugin_name='threadexception', plugin=<module '_pytest.threadexception' from 'D:\\a\\austin\\austin\\venv\\...e=None>>, <HookImpl plugin_name='logging-plugin', plugin=<_pytest.logging.LoggingPlugin object at 0x000001D9A9159580>>]
caller_kwargs = {'item': <Function test_attach_exposure[3.11-1]>}
firstresult = False

    def _multicall(
        hook_name: str,
        hook_impls: Sequence[HookImpl],
        caller_kwargs: Mapping[str, object],
        firstresult: bool,
    ) -> object | list[object]:
        """Execute a call into multiple python functions/methods and return the
        result(s).
    
        ``caller_kwargs`` comes from HookCaller.__call__().
        """
        __tracebackhide__ = True
        results: list[object] = []
        exception = None
        try:  # run impl and wrapper setup functions in a loop
            teardowns: list[Teardown] = []
            try:
                for hook_impl in reversed(hook_impls):
                    try:
                        args = [caller_kwargs[argname] for argname in hook_impl.argnames]
                    except KeyError as e:
                        # coverage bug - this is tested
                        for argname in hook_impl.argnames:  # pragma: no cover
                            if argname not in caller_kwargs:
                                raise HookCallError(
                                    f"hook call must provide argument {argname!r}"
                                ) from e
    
                    if hook_impl.hookwrapper:
                        function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args)
    
                        next(function_gen)  # first yield
                        teardowns.append(function_gen)
    
                    elif hook_impl.wrapper:
                        try:
                            # If this cast is not valid, a type error is raised below,
                            # which is the desired response.
                            res = hook_impl.function(*args)
                            function_gen = cast(Generator[None, object, object], res)
                            next(function_gen)  # first yield
                            teardowns.append(function_gen)
                        except StopIteration:
                            _raise_wrapfail(function_gen, "did not yield")
                    else:
                        res = hook_impl.function(*args)
                        if res is not None:
                            results.append(res)
                            if firstresult:  # halt further impl calls
                                break
            except BaseException as exc:
                exception = exc
        finally:
            if firstresult:  # first result hooks return a single value
                result = results[0] if results else None
            else:
                result = results
    
            # run all wrapper post-yield blocks
            for teardown in reversed(teardowns):
                try:
                    if exception is not None:
                        try:
>                           teardown.throw(exception)

venv\Lib\site-packages\pluggy\_callers.py:139: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <CaptureManager _method='no' _global_capturing=<MultiCapture out=None err=None in_=None _state='suspended' _in_suspended=False> _capture_fixture=None>
item = <Function test_attach_exposure[3.11-1]>

    @hookimpl(wrapper=True)
    def pytest_runtest_call(self, item: Item) -> Generator[None]:
        with self.item_capture("call", item):
>           return (yield)
                    ^^^^^

venv\Lib\site-packages\_pytest\capture.py:900: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

hook_name = 'pytest_runtest_call'
hook_impls = [<HookImpl plugin_name='threadexception', plugin=<module '_pytest.threadexception' from 'D:\\a\\austin\\austin\\venv\\...e=None>>, <HookImpl plugin_name='logging-plugin', plugin=<_pytest.logging.LoggingPlugin object at 0x000001D9A9159580>>]
caller_kwargs = {'item': <Function test_attach_exposure[3.11-1]>}
firstresult = False

    def _multicall(
        hook_name: str,
        hook_impls: Sequence[HookImpl],
        caller_kwargs: Mapping[str, object],
        firstresult: bool,
    ) -> object | list[object]:
        """Execute a call into multiple python functions/methods and return the
        result(s).
    
        ``caller_kwargs`` comes from HookCaller.__call__().
        """
        __tracebackhide__ = True
        results: list[object] = []
        exception = None
        try:  # run impl and wrapper setup functions in a loop
            teardowns: list[Teardown] = []
            try:
                for hook_impl in reversed(hook_impls):
                    try:
                        args = [caller_kwargs[argname] for argname in hook_impl.argnames]
                    except KeyError as e:
                        # coverage bug - this is tested
                        for argname in hook_impl.argnames:  # pragma: no cover
                            if argname not in caller_kwargs:
                                raise HookCallError(
                                    f"hook call must provide argument {argname!r}"
                                ) from e
    
                    if hook_impl.hookwrapper:
                        function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args)
    
                        next(function_gen)  # first yield
                        teardowns.append(function_gen)
    
                    elif hook_impl.wrapper:
                        try:
                            # If this cast is not valid, a type error is raised below,
                            # which is the desired response.
                            res = hook_impl.function(*args)
                            function_gen = cast(Generator[None, object, object], res)
                            next(function_gen)  # first yield
                            teardowns.append(function_gen)
                        except StopIteration:
                            _raise_wrapfail(function_gen, "did not yield")
                    else:
                        res = hook_impl.function(*args)
                        if res is not None:
                            results.append(res)
                            if firstresult:  # halt further impl calls
                                break
            except BaseException as exc:
                exception = exc
        finally:
            if firstresult:  # first result hooks return a single value
                result = results[0] if results else None
            else:
                result = results
    
            # run all wrapper post-yield blocks
            for teardown in reversed(teardowns):
                try:
                    if exception is not None:
                        try:
>                           teardown.throw(exception)

venv\Lib\site-packages\pluggy\_callers.py:139: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

item = <Function test_attach_exposure[3.11-1]>

    @hookimpl(wrapper=True)
    def pytest_runtest_call(item: Item) -> Generator[None]:
        xfailed = item.stash.get(xfailed_key, None)
        if xfailed is None:
            item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item)
    
        if xfailed and not item.config.option.runxfail and not xfailed.run:
            xfail("[NOTRUN] " + xfailed.reason)
    
        try:
>           return (yield)
                    ^^^^^

venv\Lib\site-packages\_pytest\skipping.py:268: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

hook_name = 'pytest_runtest_call'
hook_impls = [<HookImpl plugin_name='threadexception', plugin=<module '_pytest.threadexception' from 'D:\\a\\austin\\austin\\venv\\...e=None>>, <HookImpl plugin_name='logging-plugin', plugin=<_pytest.logging.LoggingPlugin object at 0x000001D9A9159580>>]
caller_kwargs = {'item': <Function test_attach_exposure[3.11-1]>}
firstresult = False

    def _multicall(
        hook_name: str,
        hook_impls: Sequence[HookImpl],
        caller_kwargs: Mapping[str, object],
        firstresult: bool,
    ) -> object | list[object]:
        """Execute a call into multiple python functions/methods and return the
        result(s).
    
        ``caller_kwargs`` comes from HookCaller.__call__().
        """
        __tracebackhide__ = True
        results: list[object] = []
        exception = None
        try:  # run impl and wrapper setup functions in a loop
            teardowns: list[Teardown] = []
            try:
                for hook_impl in reversed(hook_impls):
                    try:
                        args = [caller_kwargs[argname] for argname in hook_impl.argnames]
                    except KeyError as e:
                        # coverage bug - this is tested
                        for argname in hook_impl.argnames:  # pragma: no cover
                            if argname not in caller_kwargs:
                                raise HookCallError(
                                    f"hook call must provide argument {argname!r}"
                                ) from e
    
                    if hook_impl.hookwrapper:
                        function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args)
    
                        next(function_gen)  # first yield
                        teardowns.append(function_gen)
    
                    elif hook_impl.wrapper:
                        try:
                            # If this cast is not valid, a type error is raised below,
                            # which is the desired response.
                            res = hook_impl.function(*args)
                            function_gen = cast(Generator[None, object, object], res)
                            next(function_gen)  # first yield
                            teardowns.append(function_gen)
                        except StopIteration:
                            _raise_wrapfail(function_gen, "did not yield")
                    else:
>                       res = hook_impl.function(*args)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^

venv\Lib\site-packages\pluggy\_callers.py:121: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

item = <Function test_attach_exposure[3.11-1]>

    def pytest_runtest_call(item: Item) -> None:
        _update_current_test_var(item, "call")
        try:
            del sys.last_type
            del sys.last_value
            del sys.last_traceback
            if sys.version_info >= (3, 12, 0):
                del sys.last_exc  # type:ignore[attr-defined]
        except AttributeError:
            pass
        try:
>           item.runtest()

venv\Lib\site-packages\_pytest\runner.py:179: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <Function test_attach_exposure[3.11-1]>

    def runtest(self) -> None:
        """Execute the underlying test function."""
>       self.ihook.pytest_pyfunc_call(pyfuncitem=self)

venv\Lib\site-packages\_pytest\python.py:1720: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <HookCaller 'pytest_pyfunc_call'>
kwargs = {'pyfuncitem': <Function test_attach_exposure[3.11-1]>}
firstresult = True

    def __call__(self, **kwargs: object) -> Any:
        """Call the hook.
    
        Only accepts keyword arguments, which should match the hook
        specification.
    
        Returns the result(s) of calling all registered plugins, see
        :ref:`calling`.
        """
        assert not self.is_historic(), (
            "Cannot directly call a historic hook - use call_historic instead."
        )
        self._verify_all_args_are_provided(kwargs)
        firstresult = self.spec.opts.get("firstresult", False) if self.spec else False
        # Copy because plugins may register other plugins during iteration (#438).
>       return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

venv\Lib\site-packages\pluggy\_hooks.py:512: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <_pytest.config.PytestPluginManager object at 0x000001D9A7D23C80>
hook_name = 'pytest_pyfunc_call'
methods = [<HookImpl plugin_name='python', plugin=<module '_pytest.python' from 'D:\\a\\austin\\austin\\venv\\Lib\\site-packages\\_pytest\\python.py'>>]
kwargs = {'pyfuncitem': <Function test_attach_exposure[3.11-1]>}
firstresult = True

    def _hookexec(
        self,
        hook_name: str,
        methods: Sequence[HookImpl],
        kwargs: Mapping[str, object],
        firstresult: bool,
    ) -> object | list[object]:
        # called from all hookcaller instances.
        # enable_tracing will set its own wrapping function at self._inner_hookexec
>       return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

venv\Lib\site-packages\pluggy\_manager.py:120: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

hook_name = 'pytest_pyfunc_call'
hook_impls = [<HookImpl plugin_name='python', plugin=<module '_pytest.python' from 'D:\\a\\austin\\austin\\venv\\Lib\\site-packages\\_pytest\\python.py'>>]
caller_kwargs = {'pyfuncitem': <Function test_attach_exposure[3.11-1]>}
firstresult = True

    def _multicall(
        hook_name: str,
        hook_impls: Sequence[HookImpl],
        caller_kwargs: Mapping[str, object],
        firstresult: bool,
    ) -> object | list[object]:
        """Execute a call into multiple python functions/methods and return the
        result(s).
    
        ``caller_kwargs`` comes from HookCaller.__call__().
        """
        __tracebackhide__ = True
        results: list[object] = []
        exception = None
        try:  # run impl and wrapper setup functions in a loop
            teardowns: list[Teardown] = []
            try:
                for hook_impl in reversed(hook_impls):
                    try:
                        args = [caller_kwargs[argname] for argname in hook_impl.argnames]
                    except KeyError as e:
                        # coverage bug - this is tested
                        for argname in hook_impl.argnames:  # pragma: no cover
                            if argname not in caller_kwargs:
                                raise HookCallError(
                                    f"hook call must provide argument {argname!r}"
                                ) from e
    
                    if hook_impl.hookwrapper:
                        function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args)
    
                        next(function_gen)  # first yield
                        teardowns.append(function_gen)
    
                    elif hook_impl.wrapper:
                        try:
                            # If this cast is not valid, a type error is raised below,
                            # which is the desired response.
                            res = hook_impl.function(*args)
                            function_gen = cast(Generator[None, object, object], res)
                            next(function_gen)  # first yield
                            teardowns.append(function_gen)
                        except StopIteration:
                            _raise_wrapfail(function_gen, "did not yield")
                    else:
                        res = hook_impl.function(*args)
                        if res is not None:
                            results.append(res)
                            if firstresult:  # halt further impl calls
                                break
            except BaseException as exc:
                exception = exc
        finally:
            if firstresult:  # first result hooks return a single value
                result = results[0] if results else None
            else:
                result = results
    
            # run all wrapper post-yield blocks
            for teardown in reversed(teardowns):
                try:
                    if exception is not None:
                        try:
                            teardown.throw(exception)
                        except RuntimeError as re:
                            # StopIteration from generator causes RuntimeError
                            # even for coroutine usage - see #544
                            if (
                                isinstance(exception, StopIteration)
                                and re.__cause__ is exception
                            ):
                                teardown.close()
                                continue
                            else:
                                raise
                    else:
                        teardown.send(result)
                    # Following is unreachable for a well behaved hook wrapper.
                    # Try to force finalizers otherwise postponed till GC action.
                    # Note: close() may raise if generator handles GeneratorExit.
                    teardown.close()
                except StopIteration as si:
                    result = si.value
                    exception = None
                    continue
                except BaseException as e:
                    exception = e
                    continue
                _raise_wrapfail(teardown, "has second yield")
    
        if exception is not None:
>           raise exception

venv\Lib\site-packages\pluggy\_callers.py:167: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

hook_name = 'pytest_pyfunc_call'
hook_impls = [<HookImpl plugin_name='python', plugin=<module '_pytest.python' from 'D:\\a\\austin\\austin\\venv\\Lib\\site-packages\\_pytest\\python.py'>>]
caller_kwargs = {'pyfuncitem': <Function test_attach_exposure[3.11-1]>}
firstresult = True

    def _multicall(
        hook_name: str,
        hook_impls: Sequence[HookImpl],
        caller_kwargs: Mapping[str, object],
        firstresult: bool,
    ) -> object | list[object]:
        """Execute a call into multiple python functions/methods and return the
        result(s).
    
        ``caller_kwargs`` comes from HookCaller.__call__().
        """
        __tracebackhide__ = True
        results: list[object] = []
        exception = None
        try:  # run impl and wrapper setup functions in a loop
            teardowns: list[Teardown] = []
            try:
                for hook_impl in reversed(hook_impls):
                    try:
                        args = [caller_kwargs[argname] for argname in hook_impl.argnames]
                    except KeyError as e:
                        # coverage bug - this is tested
                        for argname in hook_impl.argnames:  # pragma: no cover
                            if argname not in caller_kwargs:
                                raise HookCallError(
                                    f"hook call must provide argument {argname!r}"
                                ) from e
    
                    if hook_impl.hookwrapper:
                        function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args)
    
                        next(function_gen)  # first yield
                        teardowns.append(function_gen)
    
                    elif hook_impl.wrapper:
                        try:
                            # If this cast is not valid, a type error is raised below,
                            # which is the desired response.
                            res = hook_impl.function(*args)
                            function_gen = cast(Generator[None, object, object], res)
                            next(function_gen)  # first yield
                            teardowns.append(function_gen)
                        except StopIteration:
                            _raise_wrapfail(function_gen, "did not yield")
                    else:
>                       res = hook_impl.function(*args)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^

venv\Lib\site-packages\pluggy\_callers.py:121: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

pyfuncitem = <Function test_attach_exposure[3.11-1]>

    @hookimpl(trylast=True)
    def pytest_pyfunc_call(pyfuncitem: Function) -> object | None:
        testfunction = pyfuncitem.obj
        if is_async_function(testfunction):
            async_fail(pyfuncitem.nodeid)
        funcargs = pyfuncitem.funcargs
        testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames}
>       result = testfunction(**testargs)
                 ^^^^^^^^^^^^^^^^^^^^^^^^

venv\Lib\site-packages\_pytest\python.py:166: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

py = '3.11', exposure = 1

    @requires_sudo
    @pytest.mark.parametrize("exposure", [1, 2])
    @allpythons()
    def test_attach_exposure(py, exposure):
        with run_python(py, target("sleepy.py"), "3") as p:
>           result = austin(
                "-i",
                "100ms",
                "-x",
                str(exposure),
                "-p",
                str(p.pid),
                expect_fail=True if sys.platform == "win32" else 256 - signal.SIGINT,
            )

test\functional\test_attach.py:79: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = Variant('austin'), timeout = 60, convert = True, expect_fail = True
args = ('-i', '100ms', '-x', '1', '-p', '1912')

    def __call__(
        self,
        *args: str,
        timeout: int = 60,
        convert: bool = True,
        expect_fail: Union[bool, int] = False,
    ) -> CompletedProcess:
        if not self.path.is_file():
            if "PYTEST_CURRENT_TEST" in os.environ:
                pytest.skip(f"{self} not available")
            else:
                raise FileNotFoundError(f"Binary {self.path} not found for {self}")
    
        extra_args = ["-b"] if "-b, --binary" in self.help else []
    
        try:
            flags = 0
            if sys.platform == "win32":
                flags = CREATE_NEW_PROCESS_GROUP
    
            result = run(
                [str(self.path)] + extra_args + list(args),
                capture_output=True,
                timeout=timeout,
                creationflags=flags,
            )
        except Exception as exc:
            if (pid := getattr(exc, "pid", None)) is not None:
                print_logs(collect_logs(self.name, pid))
            raise
    
>       return self.prepare_result(result, expect_fail, convert)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

test\utils.py:322: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = Variant('austin')
result = CompletedProcess(args=['src\\austin.exe', '-i', '100ms', '-x', '1', '-p', '1912'], returncode=4294967294, stdout=b'MOJ...b[1m10.00 Hz\x1b[0m\r\n      Error rate\x1b[0;30m . . . . . . . . \x1b[0m\x1b[1m0/10\x1b[0m (\x1b[1m0.00%\x1b[0m)\r\n")
expect_fail = True, convert = True

    def prepare_result(self, result, expect_fail, convert):
        if result.returncode in (-11, 139):  # SIGSEGV
            print(bt(self.path, result.pid))
    
        # If we are writing to stdout, check if we need to convert the stream
        if result.stdout.startswith(b"MOJ"):
            if convert:
                try:
                    result.samples, result.metadata = parse_mojo(result.stdout)
                except Exception as e:
                    dump_mojo(result.stdout)
>                   raise e

test\utils.py:335: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = Variant('austin')
result = CompletedProcess(args=['src\\austin.exe', '-i', '100ms', '-x', '1', '-p', '1912'], returncode=4294967294, stdout=b'MOJ...b[1m10.00 Hz\x1b[0m\r\n      Error rate\x1b[0;30m . . . . . . . . \x1b[0m\x1b[1m0/10\x1b[0m (\x1b[1m0.00%\x1b[0m)\r\n")
expect_fail = True, convert = True

    def prepare_result(self, result, expect_fail, convert):
        if result.returncode in (-11, 139):  # SIGSEGV
            print(bt(self.path, result.pid))
    
        # If we are writing to stdout, check if we need to convert the stream
        if result.stdout.startswith(b"MOJ"):
            if convert:
                try:
>                   result.samples, result.metadata = parse_mojo(result.stdout)
                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^

test\utils.py:332: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

data = b'MOJ\x04\x01austin\x004.0.0\x00\x01interval\x00100000\x00\x01mode\x00wall\x00\x01python\x003.11.9\x00\x02\x840\x001af...count\x0010\x00\x01duration\x001000381\x00\x01sampling\x0026,41,97\x00\x01saturation\x000/10\x00\x01errors\x000/10\x00'

    def parse_mojo(data: bytes) -> Tuple[List[AustinSample], Dict[str, str]]:
        mojo = MojoStreamReader(BytesIO(data))
>       samples = [_ for _ in mojo if isinstance(_, AustinSample)]
                              ^^^^

test\utils.py:505: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <austin.format.mojo.MojoStreamReader object at 0x000001D9AADE2390>

    def __iter__(self) -> t.Iterator[AustinEvent]:
        """Iterate over the MOJO file."""
>       for e in self.parse():
                 ^^^^^^^^^^^^

venv\Lib\site-packages\austin\format\mojo.py:664: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <austin.format.mojo.MojoStreamReader object at 0x000001D9AADE2390>

    def parse(self) -> t.Iterator[MojoEvent]:
        """Parse the MOJO file.
    
        Produces a stream of events.
        """
        # Check the MOJO header
        if self.mojo_version is None:
            if self.read(3) != b"MOJ":
                raise ValueError("Not a MOJO stream")
    
            # Get the MOJO version
            self.mojo_version = self.read_int()
    
            # Store the header bytes
            self.header = bytes(self._last_bytes)
            self._last_bytes.clear()
    
        # Parse the MOJO events
        while True:
>           if (e := self.parse_event()) is None:
                     ^^^^^^^^^^^^^^^^^^

venv\Lib\site-packages\austin\format\mojo.py:653: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <austin.format.mojo.MojoStreamReader object at 0x000001D9AADE2390>

    def parse_event(self) -> t.Optional[MojoEvent]:
        """Parse a single event."""
        try:
            (event_id,) = self.read()
        except ValueError:
            return None
    
        try:
            event = t.cast(dict, self.__handlers__)[event_id](self)
            object.__setattr__(event, "raw", bytes(self._last_bytes))
            self._last_bytes.clear()
            return event
        except KeyError as exc:
>           raise ValueError(
                f"Unhandled event: {event_id} (offset: {self._offset}, last read: {self._last_read})"
            ) from exc
E           ValueError: Unhandled event: 13 (offset: 210, last read: 1)

venv\Lib\site-packages\austin\format\mojo.py:627: ValueError
