@@ -93,7 +93,7 @@ def func(x, y):
9393 metafunc .parametrize ("y" , [5 , 6 ])
9494
9595 with pytest .raises (TypeError , match = r"^ids must be a callable or an iterable$" ):
96- metafunc .parametrize ("y" , [5 , 6 ], ids = 42 ) # type: ignore[arg-type ]
96+ metafunc .parametrize ("y" , [5 , 6 ], ids = 42 ) # type: ignore[call-overload ]
9797
9898 def test_parametrize_error_iterator (self ) -> None :
9999 def func (x ):
@@ -134,7 +134,7 @@ def func(x):
134134 fail .Exception ,
135135 match = r"parametrize\(\) call in func got an unexpected scope value 'doggy'" ,
136136 ):
137- metafunc .parametrize ("x" , [1 ], scope = "doggy" ) # type: ignore[arg-type ]
137+ metafunc .parametrize ("x" , [1 ], scope = "doggy" ) # type: ignore[call-overload ]
138138
139139 def test_parametrize_request_name (self , pytester : Pytester ) -> None :
140140 """Show proper error when 'request' is used as a parameter name in parametrize (#6183)"""
@@ -813,7 +813,7 @@ def func(x, y):
813813 fail .Exception ,
814814 match = "In func: expected Sequence or boolean for indirect, got dict" ,
815815 ):
816- metafunc .parametrize ("x, y" , [("a" , "b" )], indirect = {}) # type: ignore[arg-type ]
816+ metafunc .parametrize ("x, y" , [("a" , "b" )], indirect = {}) # type: ignore[call-overload ]
817817
818818 def test_parametrize_indirect_list_functional (self , pytester : Pytester ) -> None :
819819 """
@@ -1123,6 +1123,24 @@ def test_3(self, arg, arg2):
11231123 """
11241124 )
11251125
1126+ def test_parametrize_iterator_deprecation (self ) -> None :
1127+ """Test that using iterators for argvalues raises a deprecation warning."""
1128+
1129+ def func (x ):
1130+ pass
1131+
1132+ def data_generator ():
1133+ yield 1
1134+ yield 2
1135+
1136+ metafunc = self .Metafunc (func )
1137+
1138+ with pytest .warns (
1139+ pytest .PytestRemovedIn10Warning ,
1140+ match = r"The argvalues parameter.*uses a non-Collection iterable" ,
1141+ ):
1142+ metafunc .parametrize ("x" , data_generator ())
1143+
11261144
11271145class TestMetafuncFunctional :
11281146 def test_attributes (self , pytester : Pytester ) -> None :
@@ -1682,6 +1700,62 @@ def test_3(self, fixture):
16821700 ]
16831701 )
16841702
1703+ def test_parametrize_generator_multiple_runs (self , pytester : Pytester ) -> None :
1704+ """Test that generators in parametrize work with multiple pytest.main() (deprecated)."""
1705+ pytester .makepyfile (
1706+ """
1707+ import pytest
1708+
1709+ def data_generator():
1710+ yield 1
1711+ yield 2
1712+
1713+ @pytest.mark.parametrize("bar", data_generator())
1714+ def test_foo(bar):
1715+ pass
1716+
1717+ if __name__ == '__main__':
1718+ args = ["-q", "--collect-only"]
1719+ pytest.main(args) # First run - should work with warning
1720+ pytest.main(args) # Second run - should also work with warning
1721+ """
1722+ )
1723+ result = pytester .runpytest ("-W" , "default" )
1724+ # Should see the deprecation warnings.
1725+ result .stdout .fnmatch_lines (
1726+ [
1727+ "*PytestRemovedIn10Warning: The argvalues parameter*" ,
1728+ ]
1729+ )
1730+
1731+ def test_parametrize_iterator_class_multiple_tests (
1732+ self , pytester : Pytester
1733+ ) -> None :
1734+ """Test that iterators in parametrize on a class get exhausted (deprecated)."""
1735+ pytester .makepyfile (
1736+ """
1737+ import pytest
1738+
1739+ @pytest.mark.parametrize("n", iter(range(2)))
1740+ class Test:
1741+ def test_1(self, n):
1742+ pass
1743+
1744+ def test_2(self, n):
1745+ pass
1746+ """
1747+ )
1748+ result = pytester .runpytest ("-v" , "-W" , "default" )
1749+ # Iterator gets exhausted after first test, second test gets no parameters.
1750+ # This is deprecated.
1751+ result .assert_outcomes (passed = 2 , skipped = 1 )
1752+ # Should see the deprecation warnings.
1753+ result .stdout .fnmatch_lines (
1754+ [
1755+ "*PytestRemovedIn10Warning: The argvalues parameter*" ,
1756+ ]
1757+ )
1758+
16851759
16861760class TestMetafuncFunctionalAuto :
16871761 """Tests related to automatically find out the correct scope for
0 commit comments