@@ -635,37 +635,6 @@ def skip_quarantined_test(item):
635635 )
636636
637637
638- def skip_db_test (item ):
639- if next (item .iter_markers (name = "db_test" ), None ):
640- if next (item .iter_markers (name = "non_db_test_override" ), None ):
641- # non_db_test can override the db_test set for example on module or class level
642- return
643- pytest .skip (
644- f"The test is skipped as it is DB test and --skip-db-tests is flag is passed to pytest. { item } "
645- )
646- if next (item .iter_markers (name = "backend" ), None ):
647- # also automatically skip tests marked with `backend` marker as they are implicitly
648- # db tests
649- pytest .skip (
650- f"The test is skipped as it is DB test and --skip-db-tests is flag is passed to pytest. { item } "
651- )
652-
653-
654- def only_run_db_test (item ):
655- if next (item .iter_markers (name = "db_test" ), None ) and not next (
656- item .iter_markers (name = "non_db_test_override" ), None
657- ):
658- # non_db_test at individual level can override the db_test set for example on module or class level
659- return
660- if next (item .iter_markers (name = "backend" ), None ):
661- # Also do not skip the tests marked with `backend` marker - as it is implicitly a db test
662- return
663- pytest .skip (
664- f"The test is skipped as it is not a DB tests "
665- f"and --run-db-tests-only flag is passed to pytest. { item } "
666- )
667-
668-
669638def skip_if_integration_disabled (marker , item ):
670639 integration_name = marker .args [0 ]
671640 environment_variable_name = "INTEGRATION_" + integration_name .upper ()
@@ -712,6 +681,43 @@ def skip_if_credential_file_missing(item):
712681 pytest .skip (f"The test requires credential file { credential_path } : { item } " )
713682
714683
684+ def _is_db_test (item ) -> bool :
685+ """Check if a test item should be treated as a DB test."""
686+ if next (item .iter_markers (name = "db_test" ), None ):
687+ if next (item .iter_markers (name = "non_db_test_override" ), None ):
688+ return False
689+ return True
690+ if next (item .iter_markers (name = "backend" ), None ):
691+ return True
692+ return False
693+
694+
695+ def pytest_collection_modifyitems (config , items ):
696+ """Deselect DB/non-DB tests early so pytest-xdist workers never receive them.
697+
698+ Previously these tests were skipped at runtime via pytest_runtest_setup, which
699+ still required every xdist worker to import the test modules. With thousands of
700+ DB tests being skipped in non-DB runs, this caused excessive memory usage — enough
701+ to OOM on Python 3.14 CI runners. Deselecting during collection avoids distributing
702+ these items to workers entirely.
703+ """
704+ if not skip_db_tests and not run_db_tests_only :
705+ return
706+
707+ selected = []
708+ deselected = []
709+ for item in items :
710+ is_db = _is_db_test (item )
711+ if (skip_db_tests and is_db ) or (run_db_tests_only and not is_db ):
712+ deselected .append (item )
713+ else :
714+ selected .append (item )
715+
716+ if deselected :
717+ config .hook .pytest_deselected (items = deselected )
718+ items [:] = selected
719+
720+
715721def pytest_runtest_setup (item ):
716722 selected_integrations_list = item .config .option .integration
717723
@@ -737,10 +743,6 @@ def pytest_runtest_setup(item):
737743 skip_long_running_test (item )
738744 if not include_quarantined :
739745 skip_quarantined_test (item )
740- if skip_db_tests :
741- skip_db_test (item )
742- if run_db_tests_only :
743- only_run_db_test (item )
744746 skip_if_credential_file_missing (item )
745747
746748
0 commit comments