| cls = <class '_pytest.runner.CallInfo'>
|
| func = <function FlakyPlugin.call_and_report.<locals>._call_runtest_hook.<locals>.<lambda> at 0x00000262F106C3A0>
|
| 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:344:
|
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
|
| > 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_cli_no_python>}, 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 0x00000262ED963310>
|
| 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 0x00000262EEC78F40>>]
|
| kwargs = {'item': <Function test_cli_no_python>}, 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 0x00000262EEC78F40>>]
|
| caller_kwargs = {'item': <Function test_cli_no_python>}, 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 0x00000262EEC78F40>>]
|
| caller_kwargs = {'item': <Function test_cli_no_python>}, 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 0x00000262EEC78F40>
|
| item = <Function test_cli_no_python>
|
|
|
| @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 0x00000262EEC78F40>>]
|
| caller_kwargs = {'item': <Function test_cli_no_python>}, 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_cli_no_python>
|
|
|
| @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 0x00000262EEC78F40>>]
|
| caller_kwargs = {'item': <Function test_cli_no_python>}, 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_cli_no_python>
|
|
|
| @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:263:
|
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
|
| 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 0x00000262EEC78F40>>]
|
| caller_kwargs = {'item': <Function test_cli_no_python>}, 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_cli_no_python>
|
|
|
| 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:178:
|
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
|
| self = <Function test_cli_no_python>
|
|
|
| def runtest(self) -> None:
|
| """Execute the underlying test function."""
|
| > self.ihook.pytest_pyfunc_call(pyfuncitem=self)
|
|
|
| venv\lib\site-packages\_pytest\python.py:1671:
|
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
|
| self = <HookCaller 'pytest_pyfunc_call'>
|
| kwargs = {'pyfuncitem': <Function test_cli_no_python>}, 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 0x00000262ED963310>
|
| 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_cli_no_python>}, 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_cli_no_python>}
|
| 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_cli_no_python>}
|
| 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_cli_no_python>
|
|
|
| @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:157:
|
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
|
| def test_cli_no_python():
|
| CC = os.getenv("CC", "gcc")
|
|
|
| if platform.system() == "Windows":
|
| exe_name = "notpython.exe"
|
| else:
|
| exe_name = "notpython"
|
| dest = Path(target("notpython.c")).parent / exe_name
|
| if not dest.exists():
|
| result = run([CC, target("notpython.c"), "-o", str(dest)])
|
| assert result.returncode == 0
|
| dest.chmod(0o755)
|
|
|
| > result = austin(str(dest), expect_fail=AustinError.BINARY)
|
|
|
| test\functional\test_cli.py:57:
|
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
|
| self = Variant('austin'), timeout = 60, convert = True
|
| expect_fail = <AustinError.BINARY: 11>
|
| args = ('D:\\a\\austin\\austin\\test\\targets\\notpython.exe',)
|
|
|
| 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:
|
| result = run(
|
| [str(self.path)] + extra_args + list(args),
|
| capture_output=True,
|
| timeout=timeout,
|
| )
|
| except Exception as exc:
|
| if (pid := getattr(exc, "pid", None)) is not None:
|
| print_logs(collect_logs(self.name, pid))
|
| raise
|
|
|
| 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.stdout = demojo(result.stdout)
|
| except Exception as e:
|
| dump_mojo(result.stdout)
|
| raise e
|
| else:
|
| result.stdout = result.stdout.decode()
|
| result.stderr = result.stderr.decode()
|
|
|
| logs = collect_logs(self.name, result.pid)
|
| result.logs = logs
|
|
|
| if result.returncode != int(expect_fail):
|
| print_logs(logs)
|
| > raise RuntimeError(
|
| f"Command {self.name} returned {result.returncode} "
|
| f"while expecting {expect_fail}. Output:\n{result.stdout}\n"
|
| f"Error:\n{result.stderr}"
|
| )
|
| E RuntimeError: Command austin returned 1 while expecting 11. Output:
|
| E
|
| E Error:
|
| E [1m _ _ [0m
|
| E [1m __ _ _ _ __| |_(_)_ _ [0m
|
| E [1m/ _` | || (_-< _| | ' \ [0m
|
| E [1m\__,_|\_,_/__/\__|_|_||_| [0m [36;1m4.0.0 [0m [gcc 12.2.0]
|
| E
|
| E ❌ Cannot launch the given command or it terminated too quickly.
|
|
|
| test\utils.py:327: RuntimeError
|