Skip to content

Commit

Permalink
Fixed #35402 -- Fixed crash when DatabaseFeatures.django_test_skips r…
Browse files Browse the repository at this point in the history
…eferences a class in another test module

Previously, if a submodule skipped test classes in an adjacent submodule (same
parent module), only the running submodule was imported and an error was thrown
because getattr would not find the submodule of the to-be-skipped class. Updated
cached_import in django/utils/module_loading.py to include a check for the skipped
submodule, and import it if it is not there.

Thanks to Tim Graham for reporting this bug
  • Loading branch information
jonmcfee03 committed Apr 25, 2024
1 parent 9a9dc72 commit a0b3a19
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 9 deletions.
11 changes: 2 additions & 9 deletions django/db/backends/base/creation.py
Expand Up @@ -347,19 +347,12 @@ def mark_expected_failures_and_skips(self):
for reason, tests in self.connection.features.django_test_skips.items():
for test_name in tests:
test_case_name, _, test_method_name = test_name.rpartition(".")
if not test_method_name.startswith("test"):
test_case_name = test_name
test_method_name = None
test_app = test_name.split(".")[0]
# Importing a test app that isn't installed raises RuntimeError.
if test_app in settings.INSTALLED_APPS:
test_case = import_string(test_case_name)
if test_method_name:
test_method = getattr(test_case, test_method_name)
setattr(test_case, test_method_name, skip(reason)(test_method))
else:
setattr(test_case, "__unittest_skip__", True)
setattr(test_case, "__unittest_skip_why__", reason)
test_method = getattr(test_case, test_method_name)
setattr(test_case, test_method_name, skip(reason)(test_method))

def sql_table_creation_suffix(self):
"""
Expand Down
2 changes: 2 additions & 0 deletions django/utils/module_loading.py
Expand Up @@ -13,6 +13,8 @@ def cached_import(module_path, class_name):
and getattr(spec, "_initializing", False) is False
):
module = import_module(module_path)
if not hasattr(module, class_name):
import_module(f"{module_path}.{class_name}")
return getattr(module, class_name)


Expand Down
3 changes: 3 additions & 0 deletions tests/backends/base/test_creation.py
Expand Up @@ -292,6 +292,9 @@ def test_mark_expected_failures_and_skips(self):
"skip test class": {
"backends.base.test_creation.SkipTestClass",
},
"skip another submodule test class": {
"backends.base.test_features.TestDatabaseFeatures",
},
"skip test function": {
"backends.base.test_creation.test_skip_test_function",
},
Expand Down

0 comments on commit a0b3a19

Please sign in to comment.