diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py index dcfb10cee0f..736e88cfe94 100644 --- a/django/utils/autoreload.py +++ b/django/utils/autoreload.py @@ -9,6 +9,7 @@ import sys import threading import time import traceback +import weakref from collections import defaultdict from pathlib import Path from types import ModuleType @@ -98,7 +99,7 @@ def iter_all_python_module_files(): # This ensures cached results are returned in the usual case that modules # aren't loaded on the fly. modules_view = sorted(list(sys.modules.items()), key=lambda i: i[0]) - modules = tuple(m[1] for m in modules_view) + modules = tuple(m[1] for m in modules_view if not isinstance(m[1], weakref.ProxyTypes)) return iter_modules_and_files(modules, frozenset(_error_files)) diff --git a/tests/utils_tests/test_autoreload.py b/tests/utils_tests/test_autoreload.py index 6aa272dd9a1..de05e2d5f51 100644 --- a/tests/utils_tests/test_autoreload.py +++ b/tests/utils_tests/test_autoreload.py @@ -6,6 +6,7 @@ import sys import tempfile import threading import time +import weakref import zipfile from importlib import import_module from pathlib import Path @@ -116,6 +117,13 @@ class TestIterModulesAndFiles(SimpleTestCase): self.import_and_cleanup('test_compiled') self.assertFileFound(compiled_file) + def test_weakref_in_sys_module(self): + """iter_all_python_module_file() ignores weakref modules.""" + time_proxy = weakref.proxy(time) + sys.modules['time_proxy'] = time_proxy + self.addCleanup(lambda: sys.modules.pop('time_proxy', None)) + list(autoreload.iter_all_python_module_files()) # No crash. + class TestCommonRoots(SimpleTestCase): def test_common_roots(self):