33from unittest import mock
44
55import pytest
6+ from _pytest .config import Config
67from _pytest .config import ExitCode
78from _pytest .mark import EMPTY_PARAMETERSET_OPTION
89from _pytest .mark import MarkGenerator as Mark
10+ from _pytest .mark .structures import NodeKeywords
911from _pytest .nodes import Collector
1012from _pytest .nodes import Node
13+ from _pytest .python import Function
1114
1215
1316class TestMark :
@@ -961,7 +964,7 @@ class TestBarClass(BaseTests):
961964 # assert skipped_k == failed_k == 0
962965
963966
964- def test_addmarker_order () :
967+ def test_addmarker_order (pytestconfig : Config , monkeypatch ) -> None :
965968 session = mock .Mock ()
966969 session .own_markers = []
967970 session .parent = None
@@ -973,6 +976,53 @@ def test_addmarker_order():
973976 extracted = [x .name for x in node .iter_markers ()]
974977 assert extracted == ["baz" , "foo" , "bar" ]
975978
979+ # Check marks/keywords with Function.
980+ session .name = "session"
981+ session .keywords = NodeKeywords (session )
982+
983+ # Register markers for `--strict-markers`.
984+ added_markers = pytestconfig ._inicache ["markers" ] + [
985+ "funcmark" ,
986+ "prepended" ,
987+ "funcmark2" ,
988+ ]
989+ monkeypatch .setitem (pytestconfig ._inicache , "markers" , added_markers )
990+
991+ @pytest .mark .funcmark
992+ def f1 ():
993+ assert False , "don't call me"
994+
995+ func = Function .from_parent (node , name = "func" , callobj = f1 )
996+ expected_marks = ["funcmark" , "baz" , "foo" , "bar" ]
997+ assert [x .name for x in func .iter_markers ()] == expected_marks
998+ func .add_marker ("prepended" , append = False )
999+ assert [x .name for x in func .iter_markers ()] == ["prepended" ] + expected_marks
1000+ assert set (func .keywords ) == {
1001+ "Test" ,
1002+ "bar" ,
1003+ "baz" ,
1004+ "foo" ,
1005+ "func" ,
1006+ "funcmark" ,
1007+ "prepended" ,
1008+ "pytestmark" ,
1009+ "session" ,
1010+ }
1011+
1012+ # Changing the "obj" updates marks and keywords (lazily).
1013+ @pytest .mark .funcmark2
1014+ def f2 ():
1015+ assert False , "don't call me"
1016+
1017+ func .obj = f2
1018+ assert [x .name for x in func .iter_markers ()] == [
1019+ "prepended" ,
1020+ "funcmark2" ,
1021+ "baz" ,
1022+ "foo" ,
1023+ "bar" ,
1024+ ]
1025+
9761026
9771027@pytest .mark .filterwarnings ("ignore" )
9781028def test_markers_from_parametrize (testdir ):
0 commit comments