"""Utilities for deselecting pytest items by marker.""" from collections.abc import Set import pytest def deselect_items_by_tag( config: pytest.Config, items: list[pytest.Item], marker_name: str, active_tags: set[str], always_deselect_when_missing: Set[str] = frozenset(), ) -> None: """Deselect pytest items based on a marker tag. Items whose marker value is not in ``active_tags`` are deselected so they produce no test result (and no noise in external reporters such as Datadog). Two deselection modes: - Normal tags: only deselected when ``active_tags`` is non-empty and the tag is absent from it. An empty ``active_tags`` means "run everything". - ``always_deselect_when_missing`` tags: deselected whenever the tag is absent from ``active_tags``, regardless of whether ``active_tags`` is empty. Use this for tags that should never run unless explicitly requested (e.g. a step-function suite that requires a live state machine). Args: config: The pytest ``Config`` object (passed to ``pytest_collection_modifyitems``). items: The collected item list (mutated in place). marker_name: Name of the pytest marker to inspect. active_tags: Set of tag values that should run. always_deselect_when_missing: Tag values that are deselected whenever absent from ``active_tags``. """ remaining: list[pytest.Item] = [] deselected: list[pytest.Item] = [] for item in items: marker = item.get_closest_marker(marker_name) if not marker: remaining.append(item) continue if not marker.args: raise ValueError( f"Marker '{marker_name}' on {item.nodeid!r} requires a positional " f"tag argument, e.g. @pytest.mark.{marker_name}('my-tag')" ) tag = marker.args[0] if tag in always_deselect_when_missing and tag not in active_tags: deselected.append(item) elif ( tag not in always_deselect_when_missing and active_tags and tag not in active_tags ): deselected.append(item) else: remaining.append(item) if deselected: config.hook.pytest_deselected(items=deselected) items[:] = remaining