Opened 11 years ago
Closed 6 years ago
#24559 closed Bug (fixed)
MigrationLoader.load_disk ImportError handling differs under py3/pypy vs py2
| Reported by: | Keryn Knight | Owned by: | Jon Dufresne |
|---|---|---|---|
| Component: | Migrations | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | django@… | Triage Stage: | Ready for checkin |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Currently, within load_disk, the following happens:
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 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 travis build for a toy project, so it may not be a problem in practice, but it is at least inconsistent.
Change History (4)
comment:1 by , 11 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:2 by , 6 years ago
| Has patch: | set |
|---|
comment:3 by , 6 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
| Triage Stage: | Accepted → Ready for checkin |
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.