{"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":"validation","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/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/mark/structures.py#L462-L498","documentation":"`normalize_mark_list` iterates items passed as marks and unwraps `MarkDecorator` via its `.mark` attribute; anything that is not ultimately a `Mark` instance raises TypeError. This guards internal mark normalization used by parametrize and `pytestmark`.","triggerScenarios":"Passing a plain string, int, function, or a decorator that is not a `MarkDecorator` inside `marks=[...]` of `pytest.param`, or assigning non-mark objects to `pytestmark`.","commonSituations":"Mixing custom decorators with pytest marks; passing `pytest.mark.foo` incorrectly (e.g. `pytest.mark` itself, or an already-called decorator returning a non-mark); stale third-party helpers that return raw callables.","solutions":["Ensure each item in `marks=[...]` is a `Mark` or `MarkDecorator` (e.g. `pytest.mark.skip`, `pytest.mark.xfail(reason=...)`).","Drop custom decorators that are not pytest marks from the marks list.","If you constructed marks manually, use `pytest.Mark(name, args, kwargs)`."],"exampleFix":"# before\n@pytest.mark.parametrize('x', [pytest.param(1, marks=[my_custom_decorator)])\n# after\n@pytest.mark.parametrize('x', [pytest.param(1, marks=[pytest.mark.skip])])","handlingStrategy":"type-guard","validationCode":"from _pytest.mark.structures import Mark, MarkDecorator\ndef all_real_marks(marks) -> bool:\n    return all(isinstance(m, (Mark, MarkDecorator)) for m in marks)","typeGuard":"from _pytest.mark.structures import Mark, MarkDecorator\ndef is_mark_like(m: object) -> bool:\n    return isinstance(m, (Mark, MarkDecorator))","tryCatchPattern":null,"preventionTips":["Only put `pytest.mark.*` results in `marks=[...]`.","Keep custom decorators out of mark lists."],"tags":["pytest","marks","type-error","normalize"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}