Commit ce8367f1 authored by Karen Tracey's avatar Karen Tracey
Browse files

[1.1.X] Fixed #13348: Restored ability to load models from apps in eggs....

[1.1.X] Fixed #13348: Restored ability to load models from apps in eggs. Thanks Ramiro and metzen for pointers on how to find out if a module loaded from an egg has a particular submodule.

r12982 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.1.X@12983 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent a56b232c
Loading
Loading
Loading
Loading
+17 −13
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.datastructures import SortedDict
from django.utils.importlib import import_module
from django.utils.module_loading import module_has_submodule

import imp
import sys
@@ -72,25 +73,28 @@ class AppCache(object):
        self.handled[app_name] = None
        self.nesting_level += 1
        app_module = import_module(app_name)
        try:
            imp.find_module('models', app_module.__path__)
        except ImportError: 
            self.nesting_level -= 1
            # App has no models module, that's not a problem.
            return None
        try:
            models = import_module('.models', app_name)
        except ImportError:
            self.nesting_level -= 1
            # If the app doesn't have a models module, we can just ignore the
            # ImportError and return no models for it.
            if not module_has_submodule(app_module, 'models'):
                return None
            # But if the app does have a models module, we need to figure out
            # whether to suppress or propagate the error. If can_postpone is
            # True then it may be that the package is still being imported by
            # Python and the models module isn't available yet. So we add the
            # app to the postponed list and we'll try it again after all the
            # recursion has finished (in populate). If can_postpone is False
            # then it's time to raise the ImportError.
            else:
                if can_postpone:
                # Either the app has an error, or the package is still being
                # imported by Python and the model module isn't available yet.
                # We will check again once all the recursion has finished (in
                # populate).
                    self.postponed.append(app_name)
                    return None
                else:
                    raise

        self.nesting_level -= 1
        if models not in self.app_store:
            self.app_store[models] = len(self.app_store)
+27 −0
Original line number Diff line number Diff line
import os
import imp

def module_has_submodule(mod, submod_name):
    # If the module was loaded from an egg, __loader__ will be set and 
    # its find_module must be used to search for submodules.
    loader = getattr(mod, '__loader__', None)
    if loader:
        mod_path = "%s.%s" % (mod.__name__, submod_name)
        mod_path = mod_path[len(loader.prefix):]
        x = loader.find_module(mod_path)
        if x is None:
            # zipimport.zipimporter.find_module is documented to take
            # dotted paths but in fact through Pyton 2.7 is observed 
            # to require os.sep in place of dots...so try using os.sep
            # if the dotted path version failed to find the requested 
            # submodule.
            x = loader.find_module(mod_path.replace('.', os.sep))
        return x is not None

    try:
        imp.find_module(submod_name, mod.__path__)
        return True
    except ImportError:
        return False

+1.57 KiB

File added.

No diff preview for this file type.

+3.27 KiB

File added.

No diff preview for this file type.

+1.18 KiB

File added.

No diff preview for this file type.

Loading