collect
main.py _main
def _main(config: Config, session: Session) -> int | ExitCode | None:
config.hook.pytest_collection(session=session)
config.hook.pytest_runtestloop(session=session)
main.py pytest_collection
def pytest_collection(session: Session) -> None:
session.perform_collect()
main.py Session.perform_collect
def perform_collect(
self, args: Sequence[str] | None = None, genitems: bool = True
) -> Sequence[nodes.Item | nodes.Collector]:
args = self.config.args
for arg in args:
collection_argument = resolve_collection_argument(
self.config.invocation_params.dir,
arg,
as_pypath=self.config.option.pyargs,
)
rep = collect_one_node(self)
if rep.passed:
for node in rep.result:
self.items.extend(self.genitems(node))
self.config.pluginmanager.check_pending()
hook.pytest_collection_modifyitems(
session=self, config=self.config, items=items
)
hook.pytest_collection_finish(session=self)
runner.py collect_one_node
def collect_one_node(collector: Collector) -> CollectReport:
ihook.pytest_collectstart(collector=collector)
rep: CollectReport = ihook.pytest_make_collect_report(collector=collector)
runner.py pytest_make_collect_report
def pytest_make_collect_report(collector: Collector) -> CollectReport:
def collect() -> list[Item | Collector]:
# Before collecting, if this is a Directory, load the conftests.
# If a conftest import fails to load, it is considered a collection
# error of the Directory collector. This is why it's done inside of the
# CallInfo wrapper.
#
# Note: initial conftests are loaded early, not here.
if isinstance(collector, Directory):
collector.config.pluginmanager._loadconftestmodules(
collector.path,
collector.config.getoption("importmode"),
rootpath=collector.config.rootpath,
consider_namespace_packages=collector.config.getini(
"consider_namespace_packages"
),
)
return list(collector.collect())
call = CallInfo.from_call(
collect, "collect", reraise=(KeyboardInterrupt, SystemExit)
)
longrepr: None | tuple[str, int, str] | str | TerminalRepr = None
if not call.excinfo:
outcome: Literal["passed", "skipped", "failed"] = "passed"
result = call.result if not call.excinfo else None
rep = CollectReport(collector.nodeid, outcome, longrepr, result)
rep.call = call # type: ignore # see collect_one_node
return rep