structures.py

Overview

The [structures.py](/projects/286/67331) file is a core utility module within the pytest testing framework that defines fundamental data structures and mechanisms for managing pytest marks and parameter sets. Marks are metadata annotations applied to test functions or classes to influence test discovery, execution, and reporting (e.g., skip, xfail, parametrize). Parameter sets represent collections of input values used in parameterized tests.

This file provides:

Together, these data structures and utilities underpin pytest's powerful marking and parameterization capabilities.


Detailed Explanations

Classes


ParameterSet (NamedTuple)

A `ParameterSet` represents a single set of parameter values for a parameterized test, along with any associated marks and an optional ID.

Attributes

Class Methods


_HiddenParam (enum.Enum)

A private enum singleton used to denote hidden parameter sets (`HIDDEN_PARAM`). This allows a parameter set to be excluded from test names.


Mark (frozen dataclass)

Represents a pytest mark, which is metadata attached to tests.

Attributes

Methods


MarkDecorator (dataclass)

A decorator object used to apply `Mark` instances to test functions or classes.

Attributes

Properties

Methods


MarkGenerator

A factory class that dynamically generates `MarkDecorator` instances for arbitrary mark names. This class is exposed as the singleton `MARK_GEN` and as `pytest.mark`.


NodeKeywords (MutableMapping[str, Any])

A dictionary-like container mapping marker names to values for a given test node, supporting inheritance from parent nodes.

Attributes

Methods


Functions


istestfunc(func) -> bool

Determines if a callable is a test function (i.e., callable with a name not equal to `""`).


get_empty_parameterset_mark(config, argnames, func) -> MarkDecorator

Returns an appropriate mark to apply when a parameterized test has an empty parameter set, based on the pytest configuration option `"empty_parameter_set_mark"`.


get_unpacked_marks(obj, *, consider_mro=True) -> list[Mark]

Extracts all marks applied to an object (function or class). If the object is a class and `consider_mro` is `True`, marks from all superclasses in MRO order are aggregated.


normalize_mark_list(mark_list) -> Iterable[Mark]

Normalizes an iterable of `Mark` or `MarkDecorator` instances into a sequence of `Mark` objects, extracting the underlying mark from decorators.


store_mark(obj, mark: Mark, *, stacklevel=2) -> None

Stores a `Mark` on an object by appending it to the `pytestmark` attribute (a list). Emits a warning if the object is a fixture.


Important Implementation Details and Algorithms


Interactions with Other System Components


Usage Examples

import pytest

# Creating a parameter set with marks and id
param = pytest.param(1, 2, marks=pytest.mark.xfail, id="xfail_case")

# Applying a mark as a decorator
@pytest.mark.skip(reason="not implemented")
def test_feature():
    pass

# Using parametrize with ParameterSet
@pytest.mark.parametrize(
    ("a", "b"),
    [
        (1, 2),
        pytest.param(3, 4, id="special_case", marks=pytest.mark.xfail),
    ]
)
def test_sum(a, b):
    assert a + b >= 3

Mermaid Class Diagram

classDiagram
    class ParameterSet {
        +values: Sequence[object | NotSetType]
        +marks: Collection[MarkDecorator | Mark]
        +id: str | _HiddenParam | None
        +param(*values, marks=(), id=None)
        +extract_from(parameterset, force_tuple=False)
        +_parse_parametrize_args(argnames, argvalues)
        +_parse_parametrize_parameters(argvalues, force_tuple)
        +_for_parametrize(argnames, argvalues, func, config, nodeid)
    }

    class _HiddenParam {
        <<enum>>
        +token
    }

    class Mark {
        +name: str
        +args: tuple[Any, ...]
        +kwargs: Mapping[str, Any]
        +_param_ids_from: Mark | None
        +_param_ids_generated: Sequence[str] | None
        +combined_with(other: Mark) Mark
        +_has_param_ids() bool
    }

    class MarkDecorator {
        +mark: Mark
        +name: str
        +args: tuple[Any, ...]
        +kwargs: Mapping[str, Any]
        +with_args(*args, **kwargs) MarkDecorator
        +__call__(*args, **kwargs)
    }

    class MarkGenerator {
        +__getattr__(name: str) MarkDecorator
    }

    class NodeKeywords {
        -_markers: dict[str, Any]
        -node: Node
        -parent: Node
        +__getitem__(key: str) Any
        +__setitem__(key: str, value: Any)
        +__contains__(key: object) bool
        +update(other, **kwds)
        +__delitem__(key: str)
        +__iter__()
        +__len__()
    }

    ParameterSet ..> _HiddenParam : uses
    MarkDecorator --> Mark : wraps
    MarkGenerator --> MarkDecorator : generates
    NodeKeywords ..> "Node" : aggregates

Summary

[structures.py](/projects/286/67331) is a foundational module within pytest that defines how marks and parameter sets are represented, stored, combined, and applied to tests. It provides flexible, extensible classes and methods that enable pytest's powerful marking and parameterization system, including dynamic mark creation, parameter set management, and marker inheritance. This file is integral to the test metadata and parameter processing pipeline in pytest.