@@ -579,7 +579,10 @@ def test_should_skip():
579579 )
580580
581581
582- def test_incompatible_test_item (pytester ):
582+ def test_incompatible_test_item_no_obj_item (pytester ):
583+ """Doctests and other doctest-like custom pytest.Item subclasses are incompatible
584+ without an obj attribute on the Item. This shouldn't crash pytest-run-parallel
585+ and the test should only run on one thread"""
583586 pytester .makeconftest ("""
584587 import inspect
585588 import pytest
@@ -615,7 +618,50 @@ def test_incompatible_item():
615618 assert result .parseoutcomes ()["warnings" ] == 1
616619
617620
621+ def test_incompatible_test_item_obj_is_none (pytester ):
622+ """Doctests and other doctest-like custom pytest.Item subclasses are incompatible
623+ if the obj attribute is None. This shouldn't crash pytest-run-parallel
624+ and the test should only run on one thread"""
625+ pytester .makeconftest ("""
626+ import inspect
627+ import pytest
628+
629+ class CustomItem(pytest.Item):
630+ def __init__(self, name, parent=None, config=None, session=None, nodeid=None, function=None, **kwargs):
631+ super().__init__(name, parent, config, session, nodeid, **kwargs)
632+ self.function = function
633+ self.obj = None
634+
635+ def runtest(self):
636+ self.function()
637+
638+ @pytest.hookimpl(wrapper=True, trylast=True)
639+ def pytest_pycollect_makeitem(collector, name: str, obj: object):
640+ result = yield
641+ if not inspect.isfunction(obj):
642+ return result
643+ return CustomItem.from_parent(name=name, parent=collector, function=obj)
644+ """ )
645+
646+ pytester .makepyfile ("""
647+ import pytest
648+
649+ def test_incompatible_item():
650+ assert True
651+ """ )
652+ result = pytester .runpytest ("--parallel-threads=10" , "-v" , "-W" , "default" )
653+ result .stdout .fnmatch_lines (
654+ [
655+ "*::test_incompatible_item PASSED*" ,
656+ ]
657+ )
658+ assert result .parseoutcomes ()["warnings" ] == 1
659+ result .stdout .fnmatch_lines (["*Encountered pytest item * with no 'obj' attribute*" ])
660+
661+
618662def test_known_incompatible_test_item_doesnt_warn (pytester ):
663+ """If the Item has a _parallel_custom_item attribute, pytest-run-parallel
664+ shouldn't warn about the incompatibility"""
619665 pytester .makeconftest ("""
620666 import inspect
621667 import pytest
0 commit comments