@@ -272,6 +272,35 @@ def test_doctest_outcomes(self, pytester: Pytester):
272272 ]
273273 )
274274
275+ @pytest .mark .parametrize ("outcome" , ["skip" , "xfail" ])
276+ @pytest .mark .parametrize ("continue_on_failure" , [False , True ])
277+ def test_optionflags_restored_after_outcome (
278+ self , pytester : Pytester , outcome : str , continue_on_failure : bool
279+ ) -> None :
280+ pytester .makepyfile (
281+ f"""
282+ import pytest
283+
284+ def first():
285+ '''
286+ >>> pytest.{ outcome } ("reason") # doctest: -ELLIPSIS
287+ '''
288+
289+ def second():
290+ '''
291+ >>> print("foobar")
292+ foo...
293+ '''
294+ """
295+ )
296+ args = ["--doctest-modules" ]
297+ if continue_on_failure :
298+ args .append ("--doctest-continue-on-failure" )
299+ result = pytester .runpytest (* args )
300+ result .assert_outcomes (
301+ passed = 1 , skipped = int (outcome == "skip" ), xfailed = int (outcome == "xfail" )
302+ )
303+
275304 def test_docstring_partial_context_around_error (self , pytester : Pytester ):
276305 """Test that we show some context before the actual line of a failing
277306 doctest.
@@ -679,6 +708,59 @@ def nice_meth(self):
679708 reprec = pytester .inline_run (p , "--doctest-modules" )
680709 reprec .assertoutcome (failed = 1 , passed = 1 )
681710
711+ @pytest .mark .parametrize ("continue_on_failure" , [False , True ])
712+ @pytest .mark .parametrize ("first_example" , ["0." , "1 / 0" ])
713+ @pytest .mark .parametrize (
714+ "optionflags, directive, second_example, second_output, passed" ,
715+ [
716+ pytest .param ("ELLIPSIS" , "+NUMBER" , "1." , "0." , 0 , id = "enable-number" ),
717+ pytest .param (
718+ "" , "+ELLIPSIS" , 'print("foobar")' , "foo..." , 0 , id = "enable-ellipsis"
719+ ),
720+ pytest .param (
721+ "ELLIPSIS" ,
722+ "-ELLIPSIS" ,
723+ 'print("foobar")' ,
724+ "foo..." ,
725+ 1 ,
726+ id = "disable-ellipsis" ,
727+ ),
728+ ],
729+ )
730+ def test_optionflags_do_not_leak_between_docstrings (
731+ self ,
732+ pytester : Pytester ,
733+ continue_on_failure : bool ,
734+ first_example : str ,
735+ optionflags : str ,
736+ directive : str ,
737+ second_example : str ,
738+ second_output : str ,
739+ passed : int ,
740+ ) -> None :
741+ """A failing docstring must not change another's comparison options (#9924)."""
742+ pytester .makeini (f"[pytest]\n doctest_optionflags = { optionflags } " )
743+ pytester .makepyfile (
744+ f"""
745+ def first():
746+ '''
747+ >>> { first_example } # doctest: { directive }
748+ 2.
749+ '''
750+
751+ def second():
752+ '''
753+ >>> { second_example }
754+ { second_output }
755+ '''
756+ """
757+ )
758+ args = ["--doctest-modules" ]
759+ if continue_on_failure :
760+ args .append ("--doctest-continue-on-failure" )
761+ result = pytester .runpytest (* args )
762+ result .assert_outcomes (failed = 2 - passed , passed = passed )
763+
682764 def test_ignored_whitespace (self , pytester : Pytester ):
683765 pytester .makeini (
684766 """
0 commit comments