pytest-dev/pytest · error · TypeError

got instead of Mark

Error message

got {mark_obj!r} instead of Mark

What it means

A TypeError raised by normalize_mark_list when an element of the mark iterable exposes a `mark` attribute (i.e. is a MarkDecorator) but that attribute is not a Mark instance, or when a bare object without a `mark` attribute is not itself a Mark. The function is the bridge between user-facing MarkDecorator and internal Mark objects; it rejects anything that is neither.

Solutions

  1. Ensure every element is produced by `pytest.mark.<name>` (a MarkDecorator) or is a Mark instance.
  2. Filter the list before passing it: `[m for m in marks if isinstance(getattr(m, 'mark', m), pytest.Mark)]`.
  3. Inspect the repr in the error message to identify the offending object and its source.

Example fix

# before
marks = [pytest.mark.skip, 'fast']
@pytest.mark.parametrize('x', [pytest.param(1, marks=marks)])
# after
marks = [pytest.mark.skip, pytest.mark.fast]
Defensive patterns

Strategy: type-guard

Validate before calling

import pytest
def clean_marks(marks):
    out = []
    for m in marks:
        obj = getattr(m, 'mark', m)
        if isinstance(obj, pytest.Mark):
            out.append(m)
    return out

Type guard

import pytest
def is_mark_like(m) -> bool:
    obj = getattr(m, 'mark', m)
    return isinstance(obj, pytest.Mark)

Prevention

When it happens

Trigger: Passing a list of marks that contains a plain decorator (not @pytest.mark.xxx), a MarkDecorator for a non-mark, a Mock object, a string, or any custom object whose `mark` attr is not a Mark. Triggered during collection when pytest flattens marks from a parametrize or marker list.

Common situations: Building mark lists dynamically from data and accidentally including non-mark objects; mixing pytest.mark with unittest decorators; stale references after a refactor.

Related errors


AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11). Data as JSON: /api/errors/71a1ec4b8c9962fe. Report an issue: GitHub.

Appendix: source

Thrown at src/_pytest/mark/structures.py:480

        else:
            mark_list = [mark_attribute]
    return list(normalize_mark_list(mark_list))


def normalize_mark_list(
    mark_list: Iterable[Mark | MarkDecorator],
) -> Iterable[Mark]:
    """
    Normalize an iterable of Mark or MarkDecorator objects into a list of marks
    by retrieving the `mark` attribute on MarkDecorator instances.

    :param mark_list: marks to normalize
    :returns: A new list of the extracted Mark objects
    """
    for mark in mark_list:
        mark_obj = getattr(mark, "mark", mark)
        if not isinstance(mark_obj, Mark):
            raise TypeError(f"got {mark_obj!r} instead of Mark")
        yield mark_obj


def store_mark(obj, mark: Mark) -> None:
    """Store a Mark on an object.

    This is used to implement the Mark declarations/decorators correctly.
    """
    assert isinstance(mark, Mark), mark

    from ..fixtures import getfixturemarker

    if getfixturemarker(obj) is not None:
        fail(
            "Marks cannot be applied to fixtures.\n"
            "See docs: https://docs.pytest.org/en/stable/deprecations.html#applying-a-mark-to-a-fixture-function"
        )

View on GitHub (pinned to 0d6fbdeffa)