[logilab.common.modutils] you should avoid using modpath_from_file(), it doesn't play well with symlinks and sys.meta_path and you should use python standard loaders

The stack frame is in reversed order for practical reason, the upper one first

/usr/local/lib/python3.8/unittest/case.py line 202
198
199
200
201
202
203
204
205
                self.obj_name = callable_obj.__name__
            except AttributeError:
                self.obj_name = str(callable_obj)
            with self:
                callable_obj(*args, **kwargs)
        finally:
            # bpo-23890: manually break a reference cycle
            self = None
/usr/local/lib/python3.8/unittest/case.py line 816
812
813
814
815
816
817
818
819
               self.assertEqual(the_exception.error_code, 3)
        """
        context = _AssertRaisesContext(expected_exception, self)
        try:
            return context.handle('assertRaises', args, kwargs)
        finally:
            # bpo-23890: manually break a reference cycle
            context = None
test/test_modutils.py line 70
66
67
68
69
70
71
72
73
74
            ["arbitrary", "pkg", "test_modutils"],
        )

    def test_raise_modpath_from_file_Exception(self):
        self.assertRaises(Exception, modutils.modpath_from_file, "/turlututu")


def load_tests(loader, tests, ignore):
    from logilab.common import modutils
logilab/common/testlib.py line 465
461
462
463
464
465
466
467
468
469
        successful
        """
        kwargs = kwargs or {}
        try:
            testfunc(*args, **kwargs)
        except self.failureException:
            result.addFailure(self, self.__exc_info())
            return 1
        except KeyboardInterrupt:
logilab/common/testlib.py line 399
395
396
397
398
399
400
401
402
403
            # generative tests
            if generative:
                self._proceed_generative(result, testMethod, runcondition)
            else:
                status = self._proceed(result, testMethod)
                success = status == 0
            if not self.quiet_run(result, self.tearDown):
                return
            if not generative and success:
_pytest/unittest.py line 333
329
330
331
332
333
334
335
336
337
            # We need to update the actual bound method with self.obj, because
            # wrap_pytest_function_for_tracing replaces self.obj by a wrapper.
            setattr(self._testcase, self.name, self.obj)
            try:
                self._testcase(result=self)  # type: ignore[arg-type]
            finally:
                delattr(self._testcase, self.name)

    def _traceback_filter(
_pytest/runner.py line 173
169
170
171
172
173
174
175
176
177
        del sys.last_traceback
    except AttributeError:
        pass
    try:
        item.runtest()
    except Exception as e:
        # Store trace info to allow postmortem debugging
        sys.last_type = type(e)
        sys.last_value = e
pluggy/_callers.py line 102
 98
 99
100
101
102
103
104
105
106
                        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
pluggy/_manager.py line 119
115
116
117
118
119
120
121
122
        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)

    def register(self, plugin: _Plugin, name: str | None = None) -> str | None:
        """Register a plugin and return its name.
pluggy/_hooks.py line 501
497
498
499
500
501
502
503
504
505
        ), "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)

    def call_historic(
        self,
        result_callback: Callable[[Any], None] | None = None,
_pytest/runner.py line 266
262
263
264
265
266
267
268
269
270
    reraise: Tuple[Type[BaseException], ...] = (Exit,)
    if not item.config.getoption("usepdb", False):
        reraise += (KeyboardInterrupt,)
    return CallInfo.from_call(
        lambda: ihook(item=item, **kwds), when=when, reraise=reraise
    )


TResult = TypeVar("TResult", covariant=True)
_pytest/runner.py line 345
341
342
343
344
345
346
347
348
349
        excinfo = None
        start = timing.time()
        precise_start = timing.perf_counter()
        try:
            result: Optional[TResult] = func()
        except BaseException:
            excinfo = ExceptionInfo.from_current()
            if reraise is not None and isinstance(excinfo.value, reraise):
                raise
_pytest/runner.py line 265
261
262
263
264
265
266
267
268
        assert False, f"Unhandled runtest hook case: {when}"
    reraise: Tuple[Type[BaseException], ...] = (Exit,)
    if not item.config.getoption("usepdb", False):
        reraise += (KeyboardInterrupt,)
    return CallInfo.from_call(
        lambda: ihook(item=item, **kwds), when=when, reraise=reraise
    )

_pytest/runner.py line 226
222
223
224
225
226
227
228
229
230

def call_and_report(
    item: Item, when: Literal["setup", "call", "teardown"], log: bool = True, **kwds
) -> TestReport:
    call = call_runtest_hook(item, when, **kwds)
    hook = item.ihook
    report: TestReport = hook.pytest_runtest_makereport(item=item, call=call)
    if log:
        hook.pytest_runtest_logreport(report=report)
_pytest/runner.py line 133
129
130
131
132
133
134
135
136
137
    if rep.passed:
        if item.config.getoption("setupshow", False):
            show_test_item(item)
        if not item.config.getoption("setuponly", False):
            reports.append(call_and_report(item, "call", log))
    # If the session is about to fail or stop, teardown everything - this is
    # necessary to correctly report fixture teardown errors (see #11706)
    if item.session.shouldfail or item.session.shouldstop:
        nextitem = None
_pytest/runner.py line 114
110
111
112
113
114
115
116
117

def pytest_runtest_protocol(item: Item, nextitem: Optional[Item]) -> bool:
    ihook = item.ihook
    ihook.pytest_runtest_logstart(nodeid=item.nodeid, location=item.location)
    runtestprotocol(item, nextitem=nextitem)
    ihook.pytest_runtest_logfinish(nodeid=item.nodeid, location=item.location)
    return True

pluggy/_callers.py line 102
 98
 99
100
101
102
103
104
105
106
                        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
pluggy/_manager.py line 119
115
116
117
118
119
120
121
122
        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)

    def register(self, plugin: _Plugin, name: str | None = None) -> str | None:
        """Register a plugin and return its name.
pluggy/_hooks.py line 501
497
498
499
500
501
502
503
504
505
        ), "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)

    def call_historic(
        self,
        result_callback: Callable[[Any], None] | None = None,
_pytest/main.py line 351
347
348
349
350
351
352
353
354
355
        return True

    for i, item in enumerate(session.items):
        nextitem = session.items[i + 1] if i + 1 < len(session.items) else None
        item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
        if session.shouldfail:
            raise session.Failed(session.shouldfail)
        if session.shouldstop:
            raise session.Interrupted(session.shouldstop)
pluggy/_callers.py line 102
 98
 99
100
101
102
103
104
105
106
                        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
pluggy/_manager.py line 119
115
116
117
118
119
120
121
122
        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)

    def register(self, plugin: _Plugin, name: str | None = None) -> str | None:
        """Register a plugin and return its name.
pluggy/_hooks.py line 501
497
498
499
500
501
502
503
504
505
        ), "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)

    def call_historic(
        self,
        result_callback: Callable[[Any], None] | None = None,
_pytest/main.py line 326
322
323
324
325
326
327
328
329
330
def _main(config: Config, session: "Session") -> Optional[Union[int, ExitCode]]:
    """Default command line protocol for initialization, session,
    running tests and reporting."""
    config.hook.pytest_collection(session=session)
    config.hook.pytest_runtestloop(session=session)

    if session.testsfailed:
        return ExitCode.TESTS_FAILED
    elif session.testscollected == 0:
_pytest/main.py line 272
268
269
270
271
272
273
274
275
276
            config._do_configure()
            initstate = 1
            config.hook.pytest_sessionstart(session=session)
            initstate = 2
            session.exitstatus = doit(config, session) or 0
        except UsageError:
            session.exitstatus = ExitCode.USAGE_ERROR
            raise
        except Failed:
_pytest/main.py line 319
315
316
317
318
319
320
321
322
323
    return session.exitstatus


def pytest_cmdline_main(config: Config) -> Union[int, ExitCode]:
    return wrap_session(config, _main)


def _main(config: Config, session: "Session") -> Optional[Union[int, ExitCode]]:
    """Default command line protocol for initialization, session,
pluggy/_callers.py line 102
 98
 99
100
101
102
103
104
105
106
                        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
pluggy/_manager.py line 119
115
116
117
118
119
120
121
122
        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)

    def register(self, plugin: _Plugin, name: str | None = None) -> str | None:
        """Register a plugin and return its name.
pluggy/_hooks.py line 501
497
498
499
500
501
502
503
504
505
        ), "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)

    def call_historic(
        self,
        result_callback: Callable[[Any], None] | None = None,
_pytest/config/__init__.py line 174
170
171
172
173
174
175
176
177
178
                tw.line(line.rstrip(), red=True)
            return ExitCode.USAGE_ERROR
        else:
            try:
                ret: Union[ExitCode, int] = config.hook.pytest_cmdline_main(
                    config=config
                )
                try:
                    return ExitCode(ret)
_pytest/config/__init__.py line 197
193
194
195
196
197
198
199
200
201
    This function is not meant for programmable use; use `main()` instead.
    """
    # https://docs.python.org/3/library/signal.html#note-on-sigpipe
    try:
        code = main()
        sys.stdout.flush()
        return code
    except BrokenPipeError:
        # Python flushes standard streams on exit; redirect remaining output
pytest/__main__.py line 5
1
2
3
4
5
"""The pytest entry point."""
import pytest

if __name__ == "__main__":
    raise SystemExit(pytest.console_main())
/usr/local/lib/python3.8/runpy.py line 87
83
84
85
86
87
88
89
90
91
                       __doc__ = None,
                       __loader__ = loader,
                       __package__ = pkg_name,
                       __spec__ = mod_spec)
    exec(code, run_globals)
    return run_globals

def _run_module_code(code, init_globals=None,
                    mod_name=None, mod_spec=None,
/usr/local/lib/python3.8/runpy.py line 194
190
191
192
193
194
195
196
197
198
        sys.exit(msg)
    main_globals = sys.modules["__main__"].__dict__
    if alter_argv:
        sys.argv[0] = mod_spec.origin
    return _run_code(code, main_globals, None,
                     "__main__", mod_spec)

def run_module(mod_name, init_globals=None,
               run_name=None, alter_sys=False):