Ticket #596: pep-302.2.diff

File pep-302.2.diff, 41.8 KB (added by bhuztez, 12 years ago)

add pep-302 importers support for template

  • django/core/management/__init__.py

    diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
    index 8e83304..74bb558 100644
    a b import os  
    33import sys
    44from optparse import OptionParser, NO_DEFAULT
    55import imp
     6import pkgutil
    67import warnings
    78
    89from django.core.management.base import BaseCommand, CommandError, handle_default_options
    910from django.core.management.color import color_style
    10 from django.utils.importlib import import_module
     11from django.utils.importlib import import_module, find_package_path
    1112
    1213# For backwards compatibility: get_version() used to be in this module.
    1314from django import get_version
    def find_commands(management_dir):  
    2324
    2425    Returns an empty list if no commands are defined.
    2526    """
    26     command_dir = os.path.join(management_dir, 'commands')
    2727    try:
    28         return [f[:-3] for f in os.listdir(command_dir)
    29                 if not f.startswith('_') and f.endswith('.py')]
    30     except OSError:
     28        commands_dir = find_package_path('commands', [management_dir])[0]
     29        return [name for loader,name,ispkg in pkgutil.iter_modules([commands_dir])
     30                if not name.startswith('_') ]
     31    except ImportError:
    3132        return []
    3233
    3334def find_management_module(app_name):
    def find_management_module(app_name):  
    3940    """
    4041    parts = app_name.split('.')
    4142    parts.append('management')
    42     parts.reverse()
    43     part = parts.pop()
    44     path = None
    45 
    46     # When using manage.py, the project module is added to the path,
    47     # loaded, then removed from the path. This means that
    48     # testproject.testapp.models can be loaded in future, even if
    49     # testproject isn't in the path. When looking for the management
    50     # module, we need look for the case where the project name is part
    51     # of the app_name but the project directory itself isn't on the path.
    52     try:
    53         f, path, descr = imp.find_module(part,path)
    54     except ImportError,e:
    55         if os.path.basename(os.getcwd()) != part:
    56             raise e
     43
     44    for i in range(len(parts), 0, -1):
     45        try:
     46            path = sys.modules['.'.join(parts[:i])].__path__
     47        except AttributeError:
     48            raise ImportError("No package named %s" % parts[i-1])
     49        except KeyError:
     50            continue
     51
     52        parts = parts[i:]
     53        parts.reverse()
     54        break
     55    else:
     56        parts.reverse()
     57        part = parts.pop()
     58        path = None
     59
     60        # When using manage.py, the project module is added to the path,
     61        # loaded, then removed from the path. This means that
     62        # testproject.testapp.models can be loaded in future, even if
     63        # testproject isn't in the path. When looking for the management
     64        # module, we need look for the case where the project name is part
     65        # of the app_name but the project directory itself isn't on the path.
     66        try:
     67            path = find_package_path(part, path)
     68        except ImportError,e:
     69            if os.path.basename(os.getcwd()) != part:
     70                raise e
    5771
    5872    while parts:
    5973        part = parts.pop()
    60         f, path, descr = imp.find_module(part, path and [path] or None)
    61     return path
     74        path = find_package_path(part, path)
     75    return path[0]
    6276
    6377def load_command_class(app_name, name):
    6478    """
  • django/template/loader.py

    diff --git a/django/template/loader.py b/django/template/loader.py
    index 4185017..98ea96c 100644
    a b  
    33# This uses the TEMPLATE_LOADERS setting, which is a list of loaders to use.
    44# Each loader is expected to have this interface:
    55#
    6 #    callable(name, dirs=[])
     6#    callable(name)
    77#
    88# name is the template name.
    9 # dirs is an optional list of directories to search instead of TEMPLATE_DIRS.
    109#
    1110# The loader should return a tuple of (template_source, path). The path returned
    1211# might be shown to the user for debugging purposes, so it should identify where
    class BaseLoader(object):  
    3837    def __init__(self, *args, **kwargs):
    3938        pass
    4039
    41     def __call__(self, template_name, template_dirs=None):
    42         return self.load_template(template_name, template_dirs)
     40    def __call__(self, template_name):
     41        return self.load_template(template_name)
    4342
    44     def load_template(self, template_name, template_dirs=None):
    45         source, display_name = self.load_template_source(template_name, template_dirs)
    46         origin = make_origin(display_name, self.load_template_source, template_name, template_dirs)
     43    def load_template(self, template_name):
     44        source, display_name = self.load_template_source(template_name)
     45        origin = make_origin(display_name, self.load_template_source, template_name)
    4746        try:
    4847            template = get_template_from_string(source, origin, template_name)
    4948            return template, None
    class BaseLoader(object):  
    5453            # not exist.
    5554            return source, display_name
    5655
    57     def load_template_source(self, template_name, template_dirs=None):
     56    def load_template_source(self, template_name):
    5857        """
    5958        Returns a tuple containing the source and origin for the given template
    6059        name.
    class BaseLoader(object):  
    7170        pass
    7271
    7372class LoaderOrigin(Origin):
    74     def __init__(self, display_name, loader, name, dirs):
     73    def __init__(self, display_name, loader, name):
    7574        super(LoaderOrigin, self).__init__(display_name)
    76         self.loader, self.loadname, self.dirs = loader, name, dirs
     75        self.loader, self.loadname = loader, name
    7776
    7877    def reload(self):
    79         return self.loader(self.loadname, self.dirs)[0]
     78        return self.loader(self.loadname)[0]
    8079
    81 def make_origin(display_name, loader, name, dirs):
     80def make_origin(display_name, loader, name):
    8281    if settings.TEMPLATE_DEBUG and display_name:
    83         return LoaderOrigin(display_name, loader, name, dirs)
     82        return LoaderOrigin(display_name, loader, name)
    8483    else:
    8584        return None
    8685
    def find_template_loader(loader):  
    117116    else:
    118117        raise ImproperlyConfigured('Loader does not define a "load_template" callable template source loader')
    119118
    120 def find_template(name, dirs=None):
     119def find_template(name):
    121120    # Calculate template_source_loaders the first time the function is executed
    122121    # because putting this logic in the module-level namespace may cause
    123122    # circular import errors. See Django ticket #1292.
    def find_template(name, dirs=None):  
    131130        template_source_loaders = tuple(loaders)
    132131    for loader in template_source_loaders:
    133132        try:
    134             source, display_name = loader(name, dirs)
    135             return (source, make_origin(display_name, loader, name, dirs))
     133            source, display_name = loader(name)
     134            return (source, make_origin(display_name, loader, name))
    136135        except TemplateDoesNotExist:
    137136            pass
    138137    raise TemplateDoesNotExist(name)
  • django/template/loaders/app_directories.py

    diff --git a/django/template/loaders/app_directories.py b/django/template/loaders/app_directories.py
    index b0560b4..2db1a47 100644
    a b Wrapper for loading templates from "templates" directories in INSTALLED_APPS  
    33packages.
    44"""
    55
    6 import os
    7 import sys
     6import pkgutil
    87
    98from django.conf import settings
    10 from django.core.exceptions import ImproperlyConfigured
    119from django.template.base import TemplateDoesNotExist
    1210from django.template.loader import BaseLoader
    1311from django.utils._os import safe_join
    14 from django.utils.importlib import import_module
    1512
    16 # At compile time, cache the directories to search.
    17 fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
    18 app_template_dirs = []
    19 for app in settings.INSTALLED_APPS:
    20     try:
    21         mod = import_module(app)
    22     except ImportError, e:
    23         raise ImproperlyConfigured('ImportError %s: %s' % (app, e.args[0]))
    24     template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
    25     if os.path.isdir(template_dir):
    26         app_template_dirs.append(template_dir.decode(fs_encoding))
    27 
    28 # It won't change, so convert it to a tuple to save memory.
    29 app_template_dirs = tuple(app_template_dirs)
    3013
    3114class Loader(BaseLoader):
    3215    is_usable = True
    3316
    34     def get_template_sources(self, template_name, template_dirs=None):
    35         """
    36         Returns the absolute paths to "template_name", when appended to each
    37         directory in "template_dirs". Any paths that don't lie inside one of the
    38         template dirs are excluded from the result set, for security reasons.
    39         """
    40         if not template_dirs:
    41             template_dirs = app_template_dirs
    42         for template_dir in template_dirs:
     17    def load_template_source(self, template_name):
     18        for app in settings.INSTALLED_APPS:
     19            resource = safe_join('/templates', template_name)[1:]
    4320            try:
    44                 yield safe_join(template_dir, template_name)
    45             except UnicodeDecodeError:
    46                 # The template dir name was a bytestring that wasn't valid UTF-8.
    47                 raise
    48             except ValueError:
    49                 # The joined path was located outside of template_dir.
     21                data = pkgutil.get_data(app, resource)
     22                if data is not None:
     23                    return data, 'app:' + app + ':'+resource
     24            except Exception:
    5025                pass
    5126
    52     def load_template_source(self, template_name, template_dirs=None):
    53         for filepath in self.get_template_sources(template_name, template_dirs):
    54             try:
    55                 file = open(filepath)
    56                 try:
    57                     return (file.read().decode(settings.FILE_CHARSET), filepath)
    58                 finally:
    59                     file.close()
    60             except IOError:
    61                 pass
    6227        raise TemplateDoesNotExist(template_name)
    6328
    6429_loader = Loader()
  • django/template/loaders/cached.py

    diff --git a/django/template/loaders/cached.py b/django/template/loaders/cached.py
    index 4c25acd..eeb1e6e 100644
    a b class Loader(BaseLoader):  
    2727            self._cached_loaders = cached_loaders
    2828        return self._cached_loaders
    2929
    30     def find_template(self, name, dirs=None):
     30    def find_template(self, name):
    3131        for loader in self.loaders:
    3232            try:
    33                 template, display_name = loader(name, dirs)
    34                 return (template, make_origin(display_name, loader, name, dirs))
     33                template, display_name = loader(name)
     34                return (template, make_origin(display_name, loader, name))
    3535            except TemplateDoesNotExist:
    3636                pass
    3737        raise TemplateDoesNotExist(name)
    3838
    39     def load_template(self, template_name, template_dirs=None):
    40         key = template_name
    41         if template_dirs:
    42             # If template directories were specified, use a hash to differentiate
    43             key = '-'.join([template_name, hashlib.sha1('|'.join(template_dirs)).hexdigest()])
    44 
    45         if key not in self.template_cache:
    46             template, origin = self.find_template(template_name, template_dirs)
     39    def load_template(self, template_name):
     40        if template_name not in self.template_cache:
     41            template, origin = self.find_template(template_name)
    4742            if not hasattr(template, 'render'):
    4843                try:
    4944                    template = get_template_from_string(template, origin, template_name)
    class Loader(BaseLoader):  
    5348                    # we were asked to load. This allows for correct identification (later)
    5449                    # of the actual template that does not exist.
    5550                    return template, origin
    56             self.template_cache[key] = template
    57         return self.template_cache[key], None
     51            self.template_cache[template_name] = template
     52        return self.template_cache[template_name], None
    5853
    5954    def reset(self):
    6055        "Empty the template cache."
  • deleted file django/template/loaders/eggs.py

    diff --git a/django/template/loaders/eggs.py b/django/template/loaders/eggs.py
    deleted file mode 100644
    index 42f87a4..0000000
    + -  
    1 # Wrapper for loading templates from eggs via pkg_resources.resource_string.
    2 
    3 try:
    4     from pkg_resources import resource_string
    5 except ImportError:
    6     resource_string = None
    7 
    8 from django.template.base import TemplateDoesNotExist
    9 from django.template.loader import BaseLoader
    10 from django.conf import settings
    11 
    12 class Loader(BaseLoader):
    13     is_usable = resource_string is not None
    14 
    15     def load_template_source(self, template_name, template_dirs=None):
    16         """
    17         Loads templates from Python eggs via pkg_resource.resource_string.
    18 
    19         For every installed app, it tries to get the resource (app, template_name).
    20         """
    21         if resource_string is not None:
    22             pkg_name = 'templates/' + template_name
    23             for app in settings.INSTALLED_APPS:
    24                 try:
    25                     return (resource_string(app, pkg_name).decode(settings.FILE_CHARSET), 'egg:%s:%s' % (app, pkg_name))
    26                 except:
    27                     pass
    28         raise TemplateDoesNotExist(template_name)
    29 
    30 _loader = Loader()
  • django/template/loaders/filesystem.py

    diff --git a/django/template/loaders/filesystem.py b/django/template/loaders/filesystem.py
    index 51025ac..b926c6b 100644
    a b from django.utils._os import safe_join  
    1010class Loader(BaseLoader):
    1111    is_usable = True
    1212
    13     def get_template_sources(self, template_name, template_dirs=None):
     13    def __init__(self, template_dirs=None):
     14        self.template_dirs = template_dirs or settings.TEMPLATE_DIRS
     15
     16    def get_template_sources(self, template_name):
    1417        """
    1518        Returns the absolute paths to "template_name", when appended to each
    1619        directory in "template_dirs". Any paths that don't lie inside one of the
    1720        template dirs are excluded from the result set, for security reasons.
    1821        """
    19         if not template_dirs:
    20             template_dirs = settings.TEMPLATE_DIRS
    21         for template_dir in template_dirs:
     22        for template_dir in self.template_dirs:
    2223            try:
    2324                yield safe_join(template_dir, template_name)
    2425            except UnicodeDecodeError:
    class Loader(BaseLoader):  
    3031                # fatal).
    3132                pass
    3233
    33     def load_template_source(self, template_name, template_dirs=None):
     34    def load_template_source(self, template_name):
    3435        tried = []
    35         for filepath in self.get_template_sources(template_name, template_dirs):
     36        for filepath in self.get_template_sources(template_name):
    3637            try:
    3738                file = open(filepath)
    3839                try:
  • django/utils/importlib.py

    diff --git a/django/utils/importlib.py b/django/utils/importlib.py
    index ef4d0e4..f53abd9 100644
    a b  
    11# Taken from Python 2.7 with permission from/by the original author.
     2import os
    23import sys
     4import imp
     5import pkgutil
     6import warnings
    37
    48def _resolve_name(name, package, level):
    59    """Return the absolute name of the module to be imported."""
    def import_module(name, package=None):  
    3438        name = _resolve_name(name[level:], package, level)
    3539    __import__(name)
    3640    return sys.modules[name]
     41
     42
     43def find_package_path(name, path=None):
     44    """Finds search path for package with given name.
     45
     46    The 'path' argument defaults to ``sys.path``.
     47
     48    Raises ImportError if no search path could be found.
     49    """
     50    if path is None:
     51        path = sys.path
     52
     53    results = []
     54
     55    for path_item in path:
     56        importer = get_importer(path_item)
     57
     58        if importer is None:
     59            continue
     60
     61        try:
     62            loader = importer.find_module(name)
     63
     64            if loader is not None:
     65
     66                if not hasattr(loader, 'is_package'):
     67                    warnings.warn(
     68                        "Django cannot find search path for package '%s' ",
     69                        "under '%s', because the loader returned by '%s' does ",
     70                        "not implement 'is_package' method."%(
     71                            name,
     72                            path_item,
     73                            importer.__class__.__name__))
     74                    continue
     75
     76                if not hasattr(loader, 'get_filename'):
     77                    warnings.warn(
     78                        "Django cannot find search path for package '%s' ",
     79                        "under '%s', because the loader returned by '%s' does ",
     80                        "not implement 'get_filename' method."%(
     81                            name,
     82                            path_item,
     83                            importer.__class__.__name__))
     84                    continue
     85
     86                if loader.is_package(name):
     87                    results.append(os.path.dirname(loader.get_filename(name)))
     88        except ImportError:
     89            pass
     90
     91    if not results:
     92        raise ImportError("No package named %s" % name)
     93
     94    return results
     95
     96
     97get_importer = pkgutil.get_importer
     98
     99try:
     100    import zipimport
     101
     102    if hasattr(zipimport.zipimporter, 'get_filename'):
     103        class ZipImporter(zipimport.zipimporter):
     104            def get_filename(self, fullname):
     105                archivepath = os.path.join(self.archive, self.prefix)
     106                if self.is_package(fullname):
     107                    return os.path.join(archivepath, fullname, '__init__.py')
     108
     109                return os.path.join(archivepath, fullname + '.py')
     110
     111        def get_importer(path_item):
     112            importer = pkgutil.get_importer(path_item)
     113
     114            if isinstance(importer, zipimport.zipimporter):
     115                archivepath = os.path.join(importer.archive, importer.prefix)
     116                importer = ZipImporter(os.path.dirname(archivepath))
     117
     118            return importer
     119
     120except ImportError:
     121    pass
     122
     123
  • docs/ref/templates/api.txt

    diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt
    index 03fef1d..8154d2c 100644
    a b class. Here are the template loaders that come with Django:  
    655655    This loader is enabled by default.
    656656
    657657``django.template.loaders.app_directories.Loader``
    658     Loads templates from Django apps on the filesystem. For each app in
    659     :setting:`INSTALLED_APPS`, the loader looks for a ``templates``
    660     subdirectory. If the directory exists, Django looks for templates in there.
     658    Loads templates from Django apps. For each app in :setting:`INSTALLED_APPS`,
     659    the loader looks for a ``templates`` subdirectory. If the directory exists,
     660    Django looks for templates in there.
    661661
    662662    This means you can store templates with your individual apps. This also
    663663    makes it easy to distribute Django apps with default templates.
    class. Here are the template loaders that come with Django:  
    672672    * ``/path/to/myproject/polls/templates/foo.html``
    673673    * ``/path/to/myproject/music/templates/foo.html``
    674674
    675     Note that the loader performs an optimization when it is first imported: It
    676     caches a list of which :setting:`INSTALLED_APPS` packages have a
    677     ``templates`` subdirectory.
    678 
    679675    This loader is enabled by default.
    680676
    681 ``django.template.loaders.eggs.Loader``
    682     Just like ``app_directories`` above, but it loads templates from Python
    683     eggs rather than from the filesystem.
    684 
    685     This loader is disabled by default.
    686 
    687677``django.template.loaders.cached.Loader``
    688678    By default, the templating system will read and compile your templates every
    689679    time they need to be rendered. While the Django templating system is quite
    of the ``load_template_source()`` method implemented there::  
    838828    class Loader(app_directories.Loader):
    839829        is_usable = True
    840830
    841         def load_template(self, template_name, template_dirs=None):
    842             source, origin = self.load_template_source(template_name, template_dirs)
     831        def load_template(self, template_name):
     832            source, origin = self.load_template_source(template_name)
    843833            template = Template(source)
    844834            return template, origin
    845835
  • new file tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/nons_app_command1.py

    diff --git a/tests/regressiontests/admin_scripts/lib1/nons_app/__init__.py b/tests/regressiontests/admin_scripts/lib1/nons_app/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib1/nons_app/management/__init__.py b/tests/regressiontests/admin_scripts/lib1/nons_app/management/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/__init__.py b/tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/nons_app_command1.py b/tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/nons_app_command1.py
    new file mode 100644
    index 0000000..a393663
    - +  
     1from django.core.management.base import BaseCommand
     2
     3class Command(BaseCommand):
     4    help = 'Test managment commands in non-namespaced app'
     5    requires_model_validation = False
     6    args = ''
     7
     8    def handle(self, *labels, **options):
     9        print 'EXECUTE:nons_app_command1'
  • new file tests/regressiontests/admin_scripts/lib1/nsapps/__init__.py

    diff --git a/tests/regressiontests/admin_scripts/lib1/nons_app/models.py b/tests/regressiontests/admin_scripts/lib1/nons_app/models.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib1/npapp/__init__.py b/tests/regressiontests/admin_scripts/lib1/npapp/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib1/npapp/management.py b/tests/regressiontests/admin_scripts/lib1/npapp/management.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib1/npapp/models.py b/tests/regressiontests/admin_scripts/lib1/npapp/models.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/__init__.py b/tests/regressiontests/admin_scripts/lib1/nsapps/__init__.py
    new file mode 100644
    index 0000000..32f26d8
    - +  
     1# http://packages.python.org/distribute/setuptools.html#namespace-packages
     2try:
     3    __import__('pkg_resources').declare_namespace(__name__)
     4except ImportError:
     5    from pkgutil import extend_path
     6    __path__ = extend_path(__path__, __name__)
  • new file tests/regressiontests/admin_scripts/lib1/nsapps/contrib/__init__.py

    diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/__init__.py b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/__init__.py
    new file mode 100644
    index 0000000..32f26d8
    - +  
     1# http://packages.python.org/distribute/setuptools.html#namespace-packages
     2try:
     3    __import__('pkg_resources').declare_namespace(__name__)
     4except ImportError:
     5    from pkgutil import extend_path
     6    __path__ = extend_path(__path__, __name__)
  • new file tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/app1_command1.py

    diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/__init__.py b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/__init__.py b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/__init__.py b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/app1_command1.py b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/app1_command1.py
    new file mode 100644
    index 0000000..2f479bb
    - +  
     1from django.core.management.base import BaseCommand
     2
     3class Command(BaseCommand):
     4    help = 'Test managment commands in namespaced apps'
     5    requires_model_validation = False
     6    args = ''
     7
     8    def handle(self, *labels, **options):
     9        print 'EXECUTE:app1_command1'
  • new file tests/regressiontests/admin_scripts/lib2/nsapps/__init__.py

    diff --git a/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/models.py b/tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/models.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/__init__.py b/tests/regressiontests/admin_scripts/lib2/nsapps/__init__.py
    new file mode 100644
    index 0000000..32f26d8
    - +  
     1# http://packages.python.org/distribute/setuptools.html#namespace-packages
     2try:
     3    __import__('pkg_resources').declare_namespace(__name__)
     4except ImportError:
     5    from pkgutil import extend_path
     6    __path__ = extend_path(__path__, __name__)
  • new file tests/regressiontests/admin_scripts/lib2/nsapps/contrib/__init__.py

    diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/__init__.py b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/__init__.py
    new file mode 100644
    index 0000000..32f26d8
    - +  
     1# http://packages.python.org/distribute/setuptools.html#namespace-packages
     2try:
     3    __import__('pkg_resources').declare_namespace(__name__)
     4except ImportError:
     5    from pkgutil import extend_path
     6    __path__ = extend_path(__path__, __name__)
  • new file tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/app2_command1.py

    diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/__init__.py b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/__init__.py b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/__init__.py b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/app2_command1.py b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/app2_command1.py
    new file mode 100644
    index 0000000..b9e20a7
    - +  
     1from django.core.management.base import BaseCommand
     2
     3class Command(BaseCommand):
     4    help = 'Test managment commands in namespaced apps'
     5    requires_model_validation = False
     6    args = ''
     7
     8    def handle(self, *labels, **options):
     9        print 'EXECUTE:app2_command1'
  • new file tests/regressiontests/admin_scripts/lib3/_addsitedir.py

    diff --git a/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/models.py b/tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/models.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib3/_addsitedir.py b/tests/regressiontests/admin_scripts/lib3/_addsitedir.py
    new file mode 100644
    index 0000000..9e264d2
    - +  
     1import os.path, site; site.addsitedir(os.path.dirname(__file__))
  • new file tests/regressiontests/admin_scripts/lib3/egg_module.pth

    diff --git a/tests/regressiontests/admin_scripts/lib3/egg_module.pth b/tests/regressiontests/admin_scripts/lib3/egg_module.pth
    new file mode 100644
    index 0000000..9367ab5
    - +  
     1test_egg.egg
  • new file tests/regressiontests/admin_scripts/lib3/exapps-nspkg.pth

    diff --git a/tests/regressiontests/admin_scripts/lib3/exapps-nspkg.pth b/tests/regressiontests/admin_scripts/lib3/exapps-nspkg.pth
    new file mode 100644
    index 0000000..1f31155
    - +  
     1import sys,new,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('exapps',)); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('exapps',new.module('exapps')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p)
  • new file tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/app3_command1.py

    diff --git a/tests/regressiontests/admin_scripts/lib3/exapps/app3/__init__.py b/tests/regressiontests/admin_scripts/lib3/exapps/app3/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/__init__.py b/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/__init__.py b/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/app3_command1.py b/tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/app3_command1.py
    new file mode 100644
    index 0000000..97f5d33
    - +  
     1from django.core.management.base import BaseCommand
     2
     3class Command(BaseCommand):
     4    help = 'Test managment commands in namespaced apps'
     5    requires_model_validation = False
     6    args = ''
     7
     8    def handle(self, *labels, **options):
     9        print 'EXECUTE:app3_command1'
  • new file tests/regressiontests/admin_scripts/lib3/exapps/app3/models.py

    diff --git a/tests/regressiontests/admin_scripts/lib3/exapps/app3/models.py b/tests/regressiontests/admin_scripts/lib3/exapps/app3/models.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/admin_scripts/lib3/test_egg.egg b/tests/regressiontests/admin_scripts/lib3/test_egg.egg
    new file mode 100644
    index 0000000000000000000000000000000000000000..d9e57de006a3d602515293f8e980bf3a16fb42c0
    GIT binary patch
    literal 2210
    zcmWIWW@Zs#W&na+g#z{<8U{Fl3|Dt|T~9wZfBgWcG7g3{KxHDAuKle5O78$-K~!ZB
    z^|5C+avd@dV0&QeKT+IcWwzNt$AHBOuWGiW^E|0~S|nLhZ9Ow6Z`b?h&-X7l#KHBh
    zGf2q)-n(7*SQNg9C6^pYKAZ6`^S*BSyQv&cUcXhIbLgw+nTectc?6~3uC9yNw%@sF
    z%ItZU8-gRR@<p(DZr01@&6oUg*2%XH)tT;p3*R&VooCL-z#xL`%wYe}AZOQLy^@NO
    zseK1QE_HeT&--$}fT-Y_2pj#SlFkL2Ia9R1z3&YW$hEDwHMjD;fuxnn<YS_977M&R
    zu%dHMh3c<Wrx~B0zcgk0r=s4kFE_0Ic06}8$L(iDarse;`D34maV9DL^?37iT78$4
    zu;IH0CoB42FDd2_n0t1<bS;nS%|HFW4h3s`69&1M3mpESfSt^C-3aJd1`w7-c5zB-
    zL26z~YF=_>d`@Owb}`85T&Q|ip0Nz)2I>J}F=V|Z`33Pgsb#4-AWf<1>G8SwDWy57
    zXxfpjMv2p^%mUrw#59O{NK!eBmQ+AiA`Av67Koo#6`-amkh_o+#>Z#oWtPOp>lIYO
    zVvd0U-EcHLxrup+>8ZJ?c_m2p+{#0>M-kN?Bt1k~DUVZoa(*t*u#{pvc54yVjKvWg
    z3_F2gHQm(j`*xsy9$*5{C2S5TD4{L_2BB}CcONJzf46gee`Y}-UxUeP$C<(gLc3RV
    zY9Cwi_n@qWz2AwZxYCuY=4Gw2oV2^}(@yDPS8>aY?k=--b8BlHne^Ic|6BWKH)7Jy
    zXsq#?eWx}ep56KFx(QD9DgGB`hCMj6_@itPSErDB#zVor9U@z^*FXBlA!>Exjl$u{
    zsuuH{{dm6}Ulb7>vsbSqJM5*w#jS~~)~!DGw}|g^*kb!TX4*Er&D*q1x2SHj|9<>`
    zaDBt~!)B*vi6f<AwA2F1vq-50m~2yXiot1xkx7IZcc}%`1_S~P2OL2(QW*x*hP@O6
    zDP~|$XxP%I4y2K^LCUlMZ&dB*r3+X$So=9-?MP(}#01>A9brNPF#h2Vz?S#XjY7}-
    z2&48O8--F7pqqhS0wB!zjcf+2JV1m8W}XEV2oL~@1#Kpjcto}rTLA&l2#SXgRE;Rv
    z1{N8ZmV*im2mo2$focX)QGo0YYy}9!43Ina;536sCxHqS2mm?hH%{Y_iWiXoAV~$?
    zZJ+`M0zhuF09GEznFLWh!VSafNbCg;!rTVJ=Asrq$icY=OHM`@-Nb_GWJJDZWdo_=
    P1Hv0X>$d>aF)#oC`tnrE
  • tests/regressiontests/admin_scripts/tests.py

    literal 0
    HcmV?d00001
    
    diff --git a/tests/regressiontests/admin_scripts/tests.py b/tests/regressiontests/admin_scripts/tests.py
    index 669c6e8..6408b97 100644
    a b class AdminScriptTestCase(unittest.TestCase):  
    9191    def run_test(self, script, args, settings_file=None, apps=None):
    9292        project_dir = os.path.dirname(test_dir)
    9393        base_dir = os.path.dirname(project_dir)
     94        lib1_dir = os.path.join(os.path.dirname(__file__), 'lib1')
     95        lib2_dir = os.path.join(os.path.dirname(__file__), 'lib2')
     96        lib3_dir = os.path.join(os.path.dirname(__file__), 'lib3')
     97        eggs_dir = os.path.join(os.path.dirname(__file__), 'eggs')
    9498        ext_backend_base_dirs = self._ext_backend_paths()
    9599
    96100        # Remember the old environment
    class AdminScriptTestCase(unittest.TestCase):  
    108112            os.environ['DJANGO_SETTINGS_MODULE'] = settings_file
    109113        elif 'DJANGO_SETTINGS_MODULE' in os.environ:
    110114            del os.environ['DJANGO_SETTINGS_MODULE']
    111         python_path = [project_dir, base_dir]
     115        python_path = [project_dir, base_dir, lib1_dir, lib2_dir, lib3_dir]
    112116        python_path.extend(ext_backend_base_dirs)
    113117        os.environ[python_path_var_name] = os.pathsep.join(python_path)
    114118
    class StartProject(LiveServerTestCase, AdminScriptTestCase):  
    15631567        self.assertOutput(err, "Destination directory '%s' does not exist, please create it first." % testproject_dir)
    15641568        self.assertFalse(os.path.exists(testproject_dir))
    15651569
     1570
     1571class NamespacePackagedApps(AdminScriptTestCase):
     1572    def setUp(self):
     1573        self.write_settings('settings.py', apps=['nons_app', 'nsapps.contrib.app1','nsapps.contrib.app2','exapps.app3', 'egg_module'])
     1574        settings_file = open(os.path.join(test_dir, 'settings.py'), 'a')
     1575        settings_file.write('import _addsitedir')
     1576        settings_file.close()
     1577       
     1578    def tearDown(self):
     1579        self.remove_settings('settings.py')
     1580
     1581    def test_help(self):
     1582        out, err = self.run_manage(['help'])
     1583        self.assertNoOutput(err)
     1584        self.assertOutput(out, "nons_app_command1")
     1585        self.assertOutput(out, "app1_command1")
     1586        self.assertOutput(out, "app2_command1")
     1587        self.assertOutput(out, "app3_command1")
     1588        self.assertOutput(out, "egg_command")
     1589
     1590    def test_nons_app(self):
     1591        args = ['nons_app_command1']
     1592        out, err = self.run_manage(args)
     1593        self.assertNoOutput(err)
     1594        self.assertOutput(out, "EXECUTE:nons_app_command1")
     1595
     1596    def test_nsapps(self):
     1597        args = ['app1_command1']
     1598        out, err = self.run_manage(args)
     1599        self.assertNoOutput(err)
     1600        self.assertOutput(out, "EXECUTE:app1_command1")
     1601
     1602        args = ['app2_command1']
     1603        out, err = self.run_manage(args)
     1604        self.assertNoOutput(err)
     1605        self.assertOutput(out, "EXECUTE:app2_command1")
     1606
     1607    def test_exapps(self):
     1608        args = ['app3_command1']
     1609        out, err = self.run_manage(args)
     1610        self.assertNoOutput(err)
     1611        self.assertOutput(out, "EXECUTE:app3_command1")
     1612
     1613    def test_exapps(self):
     1614        args = ['egg_command']
     1615        out, err = self.run_manage(args)
     1616        self.assertNoOutput(err)
     1617        self.assertOutput(out, "EXECUTE:egg_command")
     1618
     1619
     1620class PreloadedNamespacePackagedApps(AdminScriptTestCase):
     1621    def setUp(self):
     1622        self.write_settings('settings.py', apps=['nsapps.contrib.app1','nsapps.contrib.app2'])
     1623        settings_file = open(os.path.join(test_dir, 'settings.py'), 'a')
     1624        settings_file.write('import nsapps')
     1625        settings_file.close()
     1626       
     1627    def tearDown(self):
     1628        self.remove_settings('settings.py')
     1629
     1630    def test_help(self):
     1631        out, err = self.run_manage(['help'])
     1632        self.assertNoOutput(err)
     1633        self.assertOutput(out, "app1_command1")
     1634        self.assertOutput(out, "app2_command1")
     1635
     1636    def test_nsapps(self):
     1637        args = ['app1_command1']
     1638        out, err = self.run_manage(args)
     1639        self.assertNoOutput(err)
     1640        self.assertOutput(out, "EXECUTE:app1_command1")
     1641
     1642        args = ['app2_command1']
     1643        out, err = self.run_manage(args)
     1644        self.assertNoOutput(err)
     1645        self.assertOutput(out, "EXECUTE:app2_command1")
     1646
     1647
     1648class NonPackageManagementApps(AdminScriptTestCase):
     1649    def setUp(self):
     1650        self.write_settings('settings.py', apps=['npapp'])
     1651        settings_file = open(os.path.join(test_dir, 'settings.py'), 'a')
     1652        settings_file.write('import npapp.management')
     1653        settings_file.close()
     1654
     1655    def tearDown(self):
     1656        self.remove_settings('settings.py')
     1657
     1658    def test_help(self):
     1659        out, err = self.run_manage(['help'])
     1660        self.assertNoOutput(err)
     1661
  • new file tests/regressiontests/templates/eggs/templatesegg.egg

    diff --git a/tests/regressiontests/templates/eggs/templatesegg.egg b/tests/regressiontests/templates/eggs/templatesegg.egg
    new file mode 100644
    index 0000000000000000000000000000000000000000..9a8f315f883b1d895f1d5926ca7ad3134c23287f
    GIT binary patch
    literal 663
    zcmWIWW@Zs#W&naW+0_mp8V1;ajMVh>ctiaFpc*c)npbFQ1mSAp<1_OzOXB183MxU$
    zAx3^eQ!W5kUXq$ykds)FT8v~kNVTZi?ca<*RUj;eMRlcKMoDfCk`>R<tl)xb0-9e^
    ziDWpsI#CpLD6VH@vS-E}BtU&YAkgsF5k$iR2&4yh5P?)OFeo%^X;cBy5Is1o#1>>=
    z-C!$&;o6Y{5MepCAcW`!S>A|6HzYs<yb+#84=GTHLIB9q+ki}v2Vmigup3<;D1;#Z
    cWcNKF6QK{q^Q@qh#=r)I1;A(*1Vudq052GO+5i9m
  • tests/regressiontests/templates/loaders.py

    literal 0
    HcmV?d00001
    
    diff --git a/tests/regressiontests/templates/loaders.py b/tests/regressiontests/templates/loaders.py
    index 5c11916..287bfdd 100644
    a b  
    11"""
    22Test cases for the template loaders
    3 
    4 Note: This test requires setuptools!
    53"""
    64
    75from django.conf import settings
    if __name__ == '__main__':  
    108    settings.configure()
    119
    1210import sys
    13 import pkg_resources
    1411import imp
    1512import StringIO
    1613import os.path
    1714
    1815from django.template import TemplateDoesNotExist, Context
    19 from django.template.loaders.eggs import Loader as EggLoader
     16from django.template.loaders.app_directories import Loader as EggLoader
    2017from django.template import loader
    2118from django.utils import unittest
    2219
    2320
    24 # Mock classes and objects for pkg_resources functions.
    25 class MockProvider(pkg_resources.NullProvider):
    26     def __init__(self, module):
    27         pkg_resources.NullProvider.__init__(self, module)
    28         self.module = module
    29 
    30     def _has(self, path):
    31         return path in self.module._resources
    32 
    33     def _isdir(self,path):
    34         return False
    35 
    36     def get_resource_stream(self, manager, resource_name):
    37         return self.module._resources[resource_name]
    38 
    39     def _get(self, path):
    40         return self.module._resources[path].read()
    41 
    42 class MockLoader(object):
    43     pass
    44 
    45 def create_egg(name, resources):
    46     """
    47     Creates a mock egg with a list of resources.
    48 
    49     name: The name of the module.
    50     resources: A dictionary of resources. Keys are the names and values the data.
    51     """
    52     egg = imp.new_module(name)
    53     egg.__loader__ = MockLoader()
    54     egg._resources = resources
    55     sys.modules[name] = egg
    56 
    57 
    5821class EggLoaderTest(unittest.TestCase):
    5922    def setUp(self):
    60         pkg_resources._provider_factories[MockLoader] = MockProvider
    61 
    62         self.empty_egg = create_egg("egg_empty", {})
    63         self.egg_1 = create_egg("egg_1", {
    64             os.path.normcase('templates/y.html') : StringIO.StringIO("y"),
    65             os.path.normcase('templates/x.txt') : StringIO.StringIO("x"),
    66         })
    67         self._old_installed_apps = settings.INSTALLED_APPS
    68         settings.INSTALLED_APPS = []
     23        self.old_path = sys.path[:]
     24        self.old_apps = settings.INSTALLED_APPS
     25        self.egg_dir = '%s/eggs' % os.path.dirname(__file__)
     26        egg_name = '%s/templatesegg.egg' % self.egg_dir
     27        sys.path.append(egg_name)
    6928
    7029    def tearDown(self):
    71         settings.INSTALLED_APPS = self._old_installed_apps
     30        settings.INSTALLED_APPS = self.old_apps
     31        sys.path = self.old_path
    7232
    7333    def test_empty(self):
    7434        "Loading any template on an empty egg should fail"
    class EggLoaderTest(unittest.TestCase):  
    8848        egg_loader = EggLoader()
    8949        contents, template_name = egg_loader.load_template_source("y.html")
    9050        self.assertEqual(contents, "y")
    91         self.assertEqual(template_name, "egg:egg_1:templates/y.html")
     51        self.assertEqual(template_name, u"app:egg_1:templates/y.html")
    9252
    9353    def test_not_installed(self):
    9454        "Loading an existent template from an egg not included in INSTALLED_APPS should fail"
  • tests/regressiontests/templates/tests.py

    diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
    index f74aa75..a13c157 100644
    a b from .nodelist import NodelistTest, ErrorIndexTest  
    3939from .smartif import SmartIfTests
    4040from .response import (TemplateResponseTest, BaseTemplateResponseTest,
    4141    CacheMiddlewareTest, SimpleTemplateResponseTest, CustomURLConfTest)
     42from .loaders import RenderToStringTest, EggLoaderTest
    4243
    43 try:
    44     from .loaders import RenderToStringTest, EggLoaderTest
    45 except ImportError, e:
    46     if "pkg_resources" in e.message:
    47         pass # If setuptools isn't installed, that's fine. Just move on.
    48     else:
    49         raise
    5044
    5145from . import filters
    5246
    class Templates(unittest.TestCase):  
    167161        restore_warnings_state(self._warnings_state)
    168162
    169163    def test_loaders_security(self):
    170         ad_loader = app_directories.Loader()
    171         fs_loader = filesystem.Loader()
    172164        def test_template_sources(path, template_dirs, expected_sources):
    173165            if isinstance(expected_sources, list):
    174166                # Fix expected sources so they are abspathed
    175167                expected_sources = [os.path.abspath(s) for s in expected_sources]
    176             # Test the two loaders (app_directores and filesystem).
    177             func1 = lambda p, t: list(ad_loader.get_template_sources(p, t))
    178             func2 = lambda p, t: list(fs_loader.get_template_sources(p, t))
    179             for func in (func1, func2):
    180                 if isinstance(expected_sources, list):
    181                     self.assertEqual(func(path, template_dirs), expected_sources)
    182                 else:
    183                     self.assertRaises(expected_sources, func, path, template_dirs)
     168            # Test filesystem loader.
     169            func = lambda p, t: list(filesystem.Loader(t).get_template_sources(p))
     170            if isinstance(expected_sources, list):
     171                self.assertEqual(func(path, template_dirs), expected_sources)
     172            else:
     173                self.assertRaises(expected_sources, func, path, template_dirs)
    184174
    185175        template_dirs = ['/dir1', '/dir2']
    186176        test_template_sources('index.html', template_dirs,
Back to Top