From 99cfb28e995388db109e2f2ed15307f09945dda8 Mon Sep 17 00:00:00 2001 From: shiningfm Date: Wed, 27 Feb 2019 16:35:30 +0100 Subject: [PATCH] Fixed #30215 -- Fixed autoreloader crash for modules without __spec__. Regression in c8720e7696ca41f3262d5369365cc1bd72a216ca. --- AUTHORS | 1 + django/utils/autoreload.py | 2 +- tests/utils_tests/test_autoreload.py | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) 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):