From e1266e50b29540c07a78ab6f544d9a5073ee8a58 Mon Sep 17 00:00:00 2001 From: Loic Bistuer Date: Fri, 6 Sep 2013 03:51:31 +0700 Subject: [PATCH] Fixed #21015 -- Fixed MigrationLoader when importlib.import_module returns a file module or an empty directory. --- django/db/migrations/loader.py | 7 +++++++ tests/migrations/faulty_migrations/__init__.py | 0 tests/migrations/faulty_migrations/file.py | 0 .../faulty_migrations/namespace/foo/__init__.py | 0 tests/migrations/test_loader.py | 16 ++++++++++++++++ 5 files changed, 23 insertions(+) create mode 100644 tests/migrations/faulty_migrations/__init__.py create mode 100644 tests/migrations/faulty_migrations/file.py create mode 100644 tests/migrations/faulty_migrations/namespace/foo/__init__.py diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index f3617764ef..c0a1208eb2 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -64,6 +64,13 @@ class MigrationLoader(object): self.unmigrated_apps.add(app_label) continue raise + else: + # PY3 will happily import empty dirs as namespaces. + if not hasattr(module, '__file__'): + continue + # Module is not a package (e.g. migrations.py). + if not hasattr(module, '__path__'): + continue self.migrated_apps.add(app_label) directory = os.path.dirname(module.__file__) # Scan for .py[c|o] files diff --git a/tests/migrations/faulty_migrations/__init__.py b/tests/migrations/faulty_migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/migrations/faulty_migrations/file.py b/tests/migrations/faulty_migrations/file.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/migrations/faulty_migrations/namespace/foo/__init__.py b/tests/migrations/faulty_migrations/namespace/foo/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/migrations/test_loader.py b/tests/migrations/test_loader.py index 6810089603..c7fe16cf9a 100644 --- a/tests/migrations/test_loader.py +++ b/tests/migrations/test_loader.py @@ -1,8 +1,11 @@ +from unittest import skipIf + from django.test import TestCase from django.test.utils import override_settings from django.db import connection from django.db.migrations.loader import MigrationLoader, AmbiguityError from django.db.migrations.recorder import MigrationRecorder +from django.utils import six class RecorderTests(TestCase): @@ -84,3 +87,16 @@ class LoaderTests(TestCase): with override_settings(MIGRATION_MODULES={"migrations": "migrations.faulty_migrations.import_error"}): with self.assertRaises(ImportError): migration_loader.load_disk() + + def test_load_module_file(self): + migration_loader = MigrationLoader(connection) + + with override_settings(MIGRATION_MODULES={"migrations": "migrations.faulty_migrations.file"}): + migration_loader.load_disk() + + @skipIf(six.PY2, "PY2 doesn't load empty dirs.") + def test_load_empty_dir(self): + migration_loader = MigrationLoader(connection) + + with override_settings(MIGRATION_MODULES={"migrations": "migrations.faulty_migrations.namespace"}): + migration_loader.load_disk()