diff --git a/AUTHORS b/AUTHORS index f305662f51..53fcee13a8 100644 --- a/AUTHORS +++ b/AUTHORS @@ -280,6 +280,7 @@ answer newbie questions, and generally made Django that much better: Flávio Juvenal da Silva Junior flavio.curella@gmail.com Florian Apolloner + Florian Moussous Francisco Albarran Cristobal François Freitag Frank Tegtmeyer diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py index 931f4b82e4..427d979a7f 100644 --- a/django/utils/autoreload.py +++ b/django/utils/autoreload.py @@ -111,7 +111,7 @@ def iter_modules_and_files(modules, extra_files): # During debugging (with PyDev) the 'typing.io' and 'typing.re' objects # are added to sys.modules, however they are types not modules and so # cause issues here. - if not isinstance(module, ModuleType) or module.__spec__ is None: + if not isinstance(module, ModuleType) or getattr(module, '__spec__', None) is None: continue spec = module.__spec__ # Modules could be loaded from places without a concrete location. If diff --git a/tests/utils_tests/test_autoreload.py b/tests/utils_tests/test_autoreload.py index cc6ea758da..3a8bf99983 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 types import weakref import zipfile from importlib import import_module @@ -124,6 +125,11 @@ class TestIterModulesAndFiles(SimpleTestCase): self.addCleanup(lambda: sys.modules.pop('time_proxy', None)) list(autoreload.iter_all_python_module_files()) # No crash. + def test_module_without_spec(self): + module = types.ModuleType('test_module') + del module.__spec__ + self.assertEqual(autoreload.iter_modules_and_files((module,), frozenset()), frozenset()) + class TestCommonRoots(SimpleTestCase): def test_common_roots(self):