@@ -1005,6 +1005,166 @@ def pytest_addoption(parser):
10051005 value = config .getini ("no_type" )
10061006 assert value == ""
10071007
1008+ def test_addini_with_aliases (self , pytester : Pytester ) -> None :
1009+ """Test that ini options can have aliases."""
1010+ pytester .makeconftest (
1011+ """
1012+ def pytest_addoption(parser):
1013+ parser.addini("new_name", "my option", aliases=["old_name"])
1014+ """
1015+ )
1016+ pytester .makeini (
1017+ """
1018+ [pytest]
1019+ old_name = hello
1020+ """
1021+ )
1022+ config = pytester .parseconfig ()
1023+ # Should be able to access via canonical name.
1024+ assert config .getini ("new_name" ) == "hello"
1025+ # Should also be able to access via alias.
1026+ assert config .getini ("old_name" ) == "hello"
1027+
1028+ def test_addini_aliases_with_canonical_in_file (self , pytester : Pytester ) -> None :
1029+ """Test that canonical name takes precedence over alias in ini file."""
1030+ pytester .makeconftest (
1031+ """
1032+ def pytest_addoption(parser):
1033+ parser.addini("new_name", "my option", aliases=["old_name"])
1034+ """
1035+ )
1036+ pytester .makeini (
1037+ """
1038+ [pytest]
1039+ old_name = from_alias
1040+ new_name = from_canonical
1041+ """
1042+ )
1043+ config = pytester .parseconfig ()
1044+ # Canonical name should take precedence.
1045+ assert config .getini ("new_name" ) == "from_canonical"
1046+ assert config .getini ("old_name" ) == "from_canonical"
1047+
1048+ def test_addini_aliases_multiple (self , pytester : Pytester ) -> None :
1049+ """Test that ini option can have multiple aliases."""
1050+ pytester .makeconftest (
1051+ """
1052+ def pytest_addoption(parser):
1053+ parser.addini("current_name", "my option", aliases=["old_name", "legacy_name"])
1054+ """
1055+ )
1056+ pytester .makeini (
1057+ """
1058+ [pytest]
1059+ old_name = value1
1060+ """
1061+ )
1062+ config = pytester .parseconfig ()
1063+ assert config .getini ("current_name" ) == "value1"
1064+ assert config .getini ("old_name" ) == "value1"
1065+ assert config .getini ("legacy_name" ) == "value1"
1066+
1067+ def test_addini_aliases_with_override_of_old (self , pytester : Pytester ) -> None :
1068+ """Test that aliases work with --override-ini -- ini sets old."""
1069+ pytester .makeconftest (
1070+ """
1071+ def pytest_addoption(parser):
1072+ parser.addini("new_name", "my option", aliases=["old_name"])
1073+ """
1074+ )
1075+ pytester .makeini (
1076+ """
1077+ [pytest]
1078+ old_name = from_file
1079+ """
1080+ )
1081+ # Override using alias.
1082+ config = pytester .parseconfig ("-o" , "old_name=overridden" )
1083+ assert config .getini ("new_name" ) == "overridden"
1084+ assert config .getini ("old_name" ) == "overridden"
1085+
1086+ # Override using canonical name.
1087+ config = pytester .parseconfig ("-o" , "new_name=overridden2" )
1088+ assert config .getini ("new_name" ) == "overridden2"
1089+
1090+ def test_addini_aliases_with_override_of_new (self , pytester : Pytester ) -> None :
1091+ """Test that aliases work with --override-ini -- ini sets new."""
1092+ pytester .makeconftest (
1093+ """
1094+ def pytest_addoption(parser):
1095+ parser.addini("new_name", "my option", aliases=["old_name"])
1096+ """
1097+ )
1098+ pytester .makeini (
1099+ """
1100+ [pytest]
1101+ new_name = from_file
1102+ """
1103+ )
1104+ # Override using alias.
1105+ config = pytester .parseconfig ("-o" , "old_name=overridden" )
1106+ assert config .getini ("new_name" ) == "overridden"
1107+ assert config .getini ("old_name" ) == "overridden"
1108+
1109+ # Override using canonical name.
1110+ config = pytester .parseconfig ("-o" , "new_name=overridden2" )
1111+ assert config .getini ("new_name" ) == "overridden2"
1112+
1113+ def test_addini_aliases_with_types (self , pytester : Pytester ) -> None :
1114+ """Test that aliases work with different types."""
1115+ pytester .makeconftest (
1116+ """
1117+ def pytest_addoption(parser):
1118+ parser.addini("mylist", "list option", type="linelist", aliases=["oldlist"])
1119+ parser.addini("mybool", "bool option", type="bool", aliases=["oldbool"])
1120+ """
1121+ )
1122+ pytester .makeini (
1123+ """
1124+ [pytest]
1125+ oldlist = line1
1126+ line2
1127+ oldbool = true
1128+ """
1129+ )
1130+ config = pytester .parseconfig ()
1131+ assert config .getini ("mylist" ) == ["line1" , "line2" ]
1132+ assert config .getini ("oldlist" ) == ["line1" , "line2" ]
1133+ assert config .getini ("mybool" ) is True
1134+ assert config .getini ("oldbool" ) is True
1135+
1136+ def test_addini_aliases_conflict_error (self , pytester : Pytester ) -> None :
1137+ """Test that registering an alias that conflicts with an existing option raises an error."""
1138+ pytester .makeconftest (
1139+ """
1140+ def pytest_addoption(parser):
1141+ parser.addini("existing", "first option")
1142+
1143+ try:
1144+ parser.addini("new_option", "second option", aliases=["existing"])
1145+ except ValueError as e:
1146+ assert "alias 'existing' conflicts with existing ini option" in str(e)
1147+ else:
1148+ assert False, "Should have raised ValueError"
1149+ """
1150+ )
1151+ pytester .parseconfig ()
1152+
1153+ def test_addini_aliases_duplicate_error (self , pytester : Pytester ) -> None :
1154+ """Test that registering the same alias twice raises an error."""
1155+ pytester .makeconftest (
1156+ """
1157+ def pytest_addoption(parser):
1158+ parser.addini("option1", "first option", aliases=["shared_alias"])
1159+ try:
1160+ parser.addini("option2", "second option", aliases=["shared_alias"])
1161+ raise AssertionError("Should have raised ValueError")
1162+ except ValueError as e:
1163+ assert "'shared_alias' is already an alias of 'option1'" in str(e)
1164+ """
1165+ )
1166+ pytester .parseconfig ()
1167+
10081168 @pytest .mark .parametrize (
10091169 "type, expected" ,
10101170 [
0 commit comments