{"record":{"id":"71a1ec4b8c9962fe","repo":"pytest-dev/pytest","slug":"got-mark-obj-r-instead-of-mark","errorCode":null,"errorMessage":"got {mark_obj!r} instead of Mark","messagePattern":"got (.+?) instead of Mark","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/_pytest/mark/structures.py","lineNumber":480,"sourceCode":"        else:\n            mark_list = [mark_attribute]\n    return list(normalize_mark_list(mark_list))\n\n\ndef normalize_mark_list(\n    mark_list: Iterable[Mark | MarkDecorator],\n) -> Iterable[Mark]:\n    \"\"\"\n    Normalize an iterable of Mark or MarkDecorator objects into a list of marks\n    by retrieving the `mark` attribute on MarkDecorator instances.\n\n    :param mark_list: marks to normalize\n    :returns: A new list of the extracted Mark objects\n    \"\"\"\n    for mark in mark_list:\n        mark_obj = getattr(mark, \"mark\", mark)\n        if not isinstance(mark_obj, Mark):\n            raise TypeError(f\"got {mark_obj!r} instead of Mark\")\n        yield mark_obj\n\n\ndef store_mark(obj, mark: Mark) -> None:\n    \"\"\"Store a Mark on an object.\n\n    This is used to implement the Mark declarations/decorators correctly.\n    \"\"\"\n    assert isinstance(mark, Mark), mark\n\n    from ..fixtures import getfixturemarker\n\n    if getfixturemarker(obj) is not None:\n        fail(\n            \"Marks cannot be applied to fixtures.\\n\"\n            \"See docs: https://docs.pytest.org/en/stable/deprecations.html#applying-a-mark-to-a-fixture-function\"\n        )\n","sourceCodeStart":462,"sourceCodeEnd":498,"githubUrl":"https://github.com/pytest-dev/pytest/blob/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/mark/structures.py#L462-L498","documentation":"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.","triggerScenarios":"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.","commonSituations":"Building mark lists dynamically from data and accidentally including non-mark objects; mixing pytest.mark with unittest decorators; stale references after a refactor.","solutions":["Ensure every element is produced by `pytest.mark.<name>` (a MarkDecorator) or is a Mark instance.","Filter the list before passing it: `[m for m in marks if isinstance(getattr(m, 'mark', m), pytest.Mark)]`.","Inspect the repr in the error message to identify the offending object and its source."],"exampleFix":"# before\nmarks = [pytest.mark.skip, 'fast']\n@pytest.mark.parametrize('x', [pytest.param(1, marks=marks)])\n# after\nmarks = [pytest.mark.skip, pytest.mark.fast]","handlingStrategy":"type-guard","validationCode":"import pytest\ndef clean_marks(marks):\n    out = []\n    for m in marks:\n        obj = getattr(m, 'mark', m)\n        if isinstance(obj, pytest.Mark):\n            out.append(m)\n    return out","typeGuard":"import pytest\ndef is_mark_like(m) -> bool:\n    obj = getattr(m, 'mark', m)\n    return isinstance(obj, pytest.Mark)","tryCatchPattern":null,"preventionTips":["Only use marks produced by pytest.mark.<name>.","Do not mix pytest marks with unittest or custom decorators.","Filter mark lists before passing to parametrize."],"tags":["pytest","marks","type-error","markdecorator","collection"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}