{{{
try:
module = import_module(module_name)
except ImportError as e:
# I hate doing this, but I don't want to squash other
import errors.
# Might be better to try a directory check directly.
if "No module named" in str(e) and MIGRATIONS_MODULE_NAME
in str(e):
self.unmigrated_apps.add(app_config.label)
continue
raise
}}}
However, the
[https://github.com/django/django/blob/2832a9b028c267997b2fd3dd0989670d57cdd08f/django/db/migrations/loader.py#L73
if statement] behaves differently under pypy & python3, because the
exception string is different.
Under python2, the following yields
{{{
>>> from importlib import import_module
>>> importlib('test_auth.migrations')
ImportError: No module named test_auth.migrations
}}}
which would hit both parts of the conditional, and end up in
`self.unmigrated_apps`
However, under python3.3.3 the exception is:
{{{
ImportError: No module named 'test_auth'
}}}
and under pypy 2.2.1 (for python 2.7.3) the exception is:
{{{
ImportError: No module named test_auth
}}}
(same as py3k, sans quotes)
Neither of these would end up `self.unmigrated_apps` because
`MIGRATIONS_MODULE_NAME` doesn't appear in the string representation,
though I suspect `import_module('testauthmigrations')` '''would''' work.
I originally noticed this because of a [https://travis-ci.org/kezabelle
/django-typesafetynet/builds/55545694 travis build] for a toy project, so
it may not be a problem in practice, but it is at least inconsistent.
--
Ticket URL: <https://code.djangoproject.com/ticket/24559>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* needs_docs: => 0
* needs_tests: => 0
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/24559#comment:1>
* has_patch: 0 => 1
Comment:
https://github.com/django/django/pull/12756
Python 2 is no longer suported, but this bug report shows why inspecting
an exception's message isn't a stable API. The above PR changes the code
to use the exception type and its "name" property.
--
Ticket URL: <https://code.djangoproject.com/ticket/24559#comment:2>
* owner: nobody => Jon Dufresne
* status: new => assigned
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/24559#comment:3>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"661e39c8d5bb05d8ebe8492912bf9f63453b279f" 661e39c8]:
{{{
#!CommitTicketReference repository=""
revision="661e39c8d5bb05d8ebe8492912bf9f63453b279f"
Fixed #24559 -- Made MigrationLoader.load_disk() catch more specific
ModuleNotFoundError.
Avoids inspecting the exception message, which is not considered a
stable API and can change across Python versions.
ModuleNotFoundError was introduced in Python 3.6. It is a subclass of
ImportError that is raised when the imported module does not exist. It
is not raised for other errors that can occur during an import. This
exception instance has the property "name" which holds the name of
module that failed to import.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/24559#comment:4>