Ticket #13464: django-importer.diff

File django-importer.diff, 5.9 KB (added by Alex Gaynor, 14 years ago)
  • django/utils/module_loading.py

    diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py
    index 9bcdd27..f251035 100644
    a b  
    1 import os
    21import imp
     2import os
     3import sys
    34
    4 def module_has_submodule(mod, submod_name):
    5     # If the module was loaded from an egg, __loader__ will be set and
    6     # its find_module must be used to search for submodules.
    7     loader = getattr(mod, '__loader__', None)
    8     if loader:
    9         mod_path = "%s.%s" % (mod.__name__.rsplit('.',1)[-1], submod_name)
    10         x = loader.find_module(mod_path)
    11         if x is None:
    12             # zipimport.zipimporter.find_module is documented to take
    13             # dotted paths but in fact through Python 2.7 is observed
    14             # to require os.sep in place of dots...so try using os.sep
    15             # if the dotted path version failed to find the requested
    16             # submodule.
    17             x = loader.find_module(mod_path.replace('.', os.sep))
    18         return x is not None
    195
    20     try:
    21         imp.find_module(submod_name, mod.__path__)
     6def module_has_submodule(package, module_name):
     7    """See if 'module' is in 'package'."""
     8    name = ".".join([package.__name__, module_name])
     9    if name in sys.modules:
    2210        return True
    23     except ImportError:
     11    for finder in sys.meta_path:
     12        if finder.find_module(name):
     13            return True
     14    for entry in package.__path__:  # No __path__, then not a package.
     15        try:
     16            # Try the cached finder.
     17            finder = sys.path_importer_cache[entry]
     18            if finder is None:
     19                # Implicit import machinery should be used.
     20                try:
     21                    file_, _, _ = imp.find_module(module_name, [entry])
     22                    if file_:
     23                        file_.close()
     24                    return True
     25                except ImportError:
     26                    continue
     27            # Else see if the finder knows of a loader.
     28            elif finder.find_module(name):
     29                return True
     30            else:
     31                continue
     32        except KeyError:
     33            # No cached finder, so try and make one.
     34            for hook in sys.path_hooks:
     35                try:
     36                    finder = hook(entry)
     37                    # XXX Could cache in sys.path_importer_cache
     38                    if finder.find_module(name):
     39                        return True
     40                    else:
     41                        # Once a finder is found, stop the search.
     42                        break
     43                except ImportError:
     44                    # Continue the search for a finder.
     45                    continue
     46            else:
     47                # No finder found.
     48                # Try the implicit import machinery if searching a directory.
     49                if os.path.isdir(entry):
     50                    try:
     51                        file_, _, _ = imp.find_module(module_name, [entry])
     52                        if file_:
     53                            file_.close()
     54                        return True
     55                    except ImportError:
     56                        pass
     57                # XXX Could insert None or NullImporter
     58    else:
     59        # Exhausted the search, so the module cannot be found.
    2460        return False
    25 
    26 
  • tests/regressiontests/templates/tests.py

    diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
    index 5902e8d..cafb2f5 100644
    a b  
    11# -*- coding: utf-8 -*-
    2 from django.conf import settings
    3 
    4 if __name__ == '__main__':
    5     # When running this file in isolation, we need to set up the configuration
    6     # before importing 'template'.
    7     settings.configure()
    82
    9 from datetime import datetime, timedelta
    10 import time
    113import os
    124import sys
     5import time
    136import traceback
    147import unittest
     8from datetime import datetime, timedelta
     9from zipimport import zipimporter
    1510
    1611from django import template
     12from django.conf import settings
    1713from django.core import urlresolvers
    1814from django.template import loader
    1915from django.template.loaders import app_directories, filesystem, cached
    class Templates(unittest.TestCase):  
    13171313        }
    13181314
    13191315
    1320 class TemplateTagLoading(unittest.TestCase):
     1316class TestFinder(object):
     1317    def __init__(self, *args, **kwargs):
     1318        self.importer = zipimporter(*args, **kwargs)
     1319   
     1320    def find_module(self, path):
     1321        importer = self.importer.find_module(path)
     1322        if importer is None:
     1323            return
     1324        return TestLoader(importer)
     1325
     1326class TestLoader(object):
     1327    def __init__(self, importer):
     1328        self.importer = importer
     1329   
     1330    def load_module(self, name):
     1331        mod = self.importer.load_module(name)
     1332        mod.__loader__ = self
     1333        return mod
    13211334
     1335
     1336class TemplateTagLoading(unittest.TestCase):
    13221337    def setUp(self):
    13231338        self.old_path = sys.path
    13241339        self.old_apps = settings.INSTALLED_APPS
    class TemplateTagLoading(unittest.TestCase):  
    13511366        except template.TemplateSyntaxError, e:
    13521367            self.assertTrue('ImportError' in e.args[0])
    13531368            self.assertTrue('Xtemplate' in e.args[0])
     1369   
     1370    def test_custom_loader_error(self):
     1371        sys.path_hooks.insert(0, TestFinder)
     1372        sys.path_importer_cache.clear()
     1373
     1374        ttext = "{% load broken_egg %}"
     1375        egg_name = '%s/tagsegg.egg' % self.egg_dir
     1376        sys.path.append(egg_name)
     1377        settings.INSTALLED_APPS = ('tagsegg',)
     1378
     1379        self.assertRaises(template.TemplateSyntaxError, template.Template, ttext)
     1380        try:
     1381            template.Template(ttext)
     1382        except template.TemplateSyntaxError, e:
     1383            self.assertTrue('ImportError' in e.args[0])
     1384            self.assertTrue('Xtemplate' in e.args[0])
     1385        sys.path_hooks.pop(0)
    13541386
    13551387    def test_load_working_egg(self):
    13561388        ttext = "{% load working_egg %}"
Back to Top