Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: bhuztez/django
...
head fork: bhuztez/django
  • 11 commits
  • 52 files changed
  • 0 commit comments
  • 1 contributor
Showing with 663 additions and 335 deletions.
  1. +63 −112 django/contrib/staticfiles/finders.py
  2. +2 −2 django/contrib/staticfiles/management/commands/findstatic.py
  3. +8 −7 django/contrib/staticfiles/views.py
  4. +128 −0 django/core/files/storage.py
  5. +35 −26 django/core/management/__init__.py
  6. +60 −31 django/core/management/commands/loaddata.py
  7. +5 −7 django/db/utils.py
  8. +15 −19 django/template/loader.py
  9. +21 −45 django/template/loaders/app_directories.py
  10. +5 −8 django/template/loaders/cached.py
  11. +0 −35 django/template/loaders/eggs.py
  12. +9 −8 django/template/loaders/filesystem.py
  13. +87 −0 django/utils/importlib.py
  14. +21 −16 django/utils/translation/trans_real.py
  15. +2 −2 docs/ref/templates/api.txt
  16. 0  tests/regressiontests/admin_scripts/lib1/nons_app/__init__.py
  17. 0  tests/regressiontests/admin_scripts/lib1/nons_app/management/__init__.py
  18. 0  tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/__init__.py
  19. +9 −0 tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/nons_app_command1.py
  20. 0  tests/regressiontests/admin_scripts/lib1/nons_app/models.py
  21. 0  tests/regressiontests/admin_scripts/lib1/npapp/__init__.py
  22. 0  tests/regressiontests/admin_scripts/lib1/npapp/management.py
  23. 0  tests/regressiontests/admin_scripts/lib1/npapp/models.py
  24. +6 −0 tests/regressiontests/admin_scripts/lib1/nsapps/__init__.py
  25. +6 −0 tests/regressiontests/admin_scripts/lib1/nsapps/contrib/__init__.py
  26. 0  tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/__init__.py
  27. 0  tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/__init__.py
  28. 0  tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/__init__.py
  29. +9 −0 tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/app1_command1.py
  30. 0  tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/models.py
  31. +6 −0 tests/regressiontests/admin_scripts/lib2/nsapps/__init__.py
  32. +6 −0 tests/regressiontests/admin_scripts/lib2/nsapps/contrib/__init__.py
  33. 0  tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/__init__.py
  34. 0  tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/__init__.py
  35. 0  tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/__init__.py
  36. +9 −0 tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/app2_command1.py
  37. 0  tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/models.py
  38. +1 −0  tests/regressiontests/admin_scripts/lib3/_addsitedir.py
  39. +1 −0  tests/regressiontests/admin_scripts/lib3/egg_module.pth
  40. +1 −0  tests/regressiontests/admin_scripts/lib3/exapps-nspkg.pth
  41. 0  tests/regressiontests/admin_scripts/lib3/exapps/app3/__init__.py
  42. 0  tests/regressiontests/admin_scripts/lib3/exapps/app3/management/__init__.py
  43. 0  tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/__init__.py
  44. +9 −0 tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/app3_command1.py
  45. 0  tests/regressiontests/admin_scripts/lib3/exapps/app3/models.py
  46. BIN  tests/regressiontests/admin_scripts/lib3/test_egg.egg
  47. +99 −1 tests/regressiontests/admin_scripts/tests.py
  48. BIN  tests/regressiontests/i18n/eggs/localeegg.egg
  49. +28 −0 tests/regressiontests/i18n/tests.py
  50. +3 −3 tests/regressiontests/staticfiles_tests/tests.py
  51. +3 −3 tests/regressiontests/templates/loaders.py
  52. +6 −10 tests/regressiontests/templates/tests.py
175 django/contrib/staticfiles/finders.py
View
@@ -1,7 +1,7 @@
import os
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
-from django.core.files.storage import default_storage, Storage, FileSystemStorage
+from django.core.files.storage import default_storage, Storage, FileSystemStorage, AppDirectoryStorage
from django.utils.datastructures import SortedDict
from django.utils.functional import empty, memoize, LazyObject
from django.utils.importlib import import_module
@@ -38,16 +38,56 @@ def list(self, ignore_patterns):
raise NotImplementedError()
-class FileSystemFinder(BaseFinder):
+class BaseStoragesFinder(BaseFinder):
+
+ def __init__(self):
+ self.storages = SortedDict()
+
+ def _find_location(self, storage, path):
+ if getattr(storage, 'prefix', False):
+ prefix = '%s%s' % (storage.prefix, os.sep)
+ if not path.startswith(prefix):
+ return None
+
+ path = path[len(prefix):]
+
+ if storage.exists(path):
+ return path
+
+ def find(self, path, all=False):
+ """
+ Looks for files in storages.
+ """
+ matches = []
+ for storage in self.storages.itervalues():
+ matched_path = self._find_location(storage, path)
+
+ if matched_path:
+ if not all:
+ return (storage, matched_path)
+ matches.append((storage, matched_path))
+
+ return matches
+
+ def list(self, ignore_patterns):
+ """
+ List all files in all storages.
+ """
+ for storage in self.storages.itervalues():
+ if storage.exists(''):
+ for path in utils.get_files(storage, ignore_patterns):
+ yield path, storage
+
+
+class FileSystemFinder(BaseStoragesFinder):
"""
A static files finder that uses the ``STATICFILES_DIRS`` setting
to locate files.
"""
- def __init__(self, apps=None, *args, **kwargs):
- # List of locations with static files
- self.locations = []
- # Maps dir paths to an appropriate storage instance
- self.storages = SortedDict()
+ def __init__(self):
+ super(FileSystemFinder, self).__init__()
+ locations = []
+
if not isinstance(settings.STATICFILES_DIRS, (list, tuple)):
raise ImproperlyConfigured(
"Your STATICFILES_DIRS setting is not a tuple or list; "
@@ -61,112 +101,27 @@ def __init__(self, apps=None, *args, **kwargs):
raise ImproperlyConfigured(
"The STATICFILES_DIRS setting should "
"not contain the STATIC_ROOT setting")
- if (prefix, root) not in self.locations:
- self.locations.append((prefix, root))
- for prefix, root in self.locations:
+ if (prefix, root) not in locations:
+ locations.append((prefix, root))
+ for prefix, root in locations:
filesystem_storage = FileSystemStorage(location=root)
filesystem_storage.prefix = prefix
self.storages[root] = filesystem_storage
- super(FileSystemFinder, self).__init__(*args, **kwargs)
- def find(self, path, all=False):
- """
- Looks for files in the extra locations
- as defined in ``STATICFILES_DIRS``.
- """
- matches = []
- for prefix, root in self.locations:
- matched_path = self.find_location(root, path, prefix)
- if matched_path:
- if not all:
- return matched_path
- matches.append(matched_path)
- return matches
-
- def find_location(self, root, path, prefix=None):
- """
- Finds a requested static file in a location, returning the found
- absolute path (or ``None`` if no match).
- """
- if prefix:
- prefix = '%s%s' % (prefix, os.sep)
- if not path.startswith(prefix):
- return None
- path = path[len(prefix):]
- path = safe_join(root, path)
- if os.path.exists(path):
- return path
-
- def list(self, ignore_patterns):
- """
- List all files in all locations.
- """
- for prefix, root in self.locations:
- storage = self.storages[root]
- for path in utils.get_files(storage, ignore_patterns):
- yield path, storage
-
-class AppDirectoriesFinder(BaseFinder):
+class AppDirectoriesFinder(BaseStoragesFinder):
"""
A static files finder that looks in the directory of each app as
specified in the source_dir attribute of the given storage class.
"""
- storage_class = AppStaticStorage
+ def __init__(self, apps=None):
+ super(AppDirectoriesFinder, self).__init__()
- def __init__(self, apps=None, *args, **kwargs):
- # The list of apps that are handled
- self.apps = []
- # Mapping of app module paths to storage instances
- self.storages = SortedDict()
if apps is None:
apps = settings.INSTALLED_APPS
for app in apps:
- app_storage = self.storage_class(app)
- if os.path.isdir(app_storage.location):
- self.storages[app] = app_storage
- if app not in self.apps:
- self.apps.append(app)
- super(AppDirectoriesFinder, self).__init__(*args, **kwargs)
-
- def list(self, ignore_patterns):
- """
- List all files in all app storages.
- """
- for storage in six.itervalues(self.storages):
- if storage.exists(''): # check if storage location exists
- for path in utils.get_files(storage, ignore_patterns):
- yield path, storage
-
- def find(self, path, all=False):
- """
- Looks for files in the app directories.
- """
- matches = []
- for app in self.apps:
- match = self.find_in_app(app, path)
- if match:
- if not all:
- return match
- matches.append(match)
- return matches
-
- def find_in_app(self, app, path):
- """
- Find a requested static file in an app's static locations.
- """
- storage = self.storages.get(app, None)
- if storage:
- if storage.prefix:
- prefix = '%s%s' % (storage.prefix, os.sep)
- if not path.startswith(prefix):
- return None
- path = path[len(prefix):]
- # only try to find a file if the source dir actually exists
- if storage.exists(path):
- matched_path = storage.path(path)
- if matched_path:
- return matched_path
+ app_storage = AppDirectoryStorage(app, 'static')
+ self.storages[app] = app_storage
class BaseStorageFinder(BaseFinder):
@@ -192,16 +147,11 @@ def find(self, path, all=False):
"""
Looks for files in the default file storage, if it's local.
"""
- try:
- self.storage.path('')
- except NotImplementedError:
- pass
- else:
- if self.storage.exists(path):
- match = self.storage.path(path)
- if all:
- match = [match]
- return match
+ if self.storage.exists(path):
+ match = (self.storage, path)
+ if all:
+ match = [match]
+ return match
return []
def list(self, ignore_patterns):
@@ -239,8 +189,9 @@ def find(path, all=False):
result = finder.find(path, all=all)
if not all and result:
return result
- if not isinstance(result, (list, tuple)):
- result = [result]
+ # if not isinstance(result, (list, tuple)):
+ # result = [result]
+ assert isinstance(result, list)
matches.extend(result)
if matches:
return matches
4 django/contrib/staticfiles/management/commands/findstatic.py
View
@@ -21,10 +21,10 @@ def handle_label(self, path, **options):
result = finders.find(path, all=options['all'])
path = smart_text(path)
if result:
- if not isinstance(result, (list, tuple)):
+ if not isinstance(result, list):
result = [result]
output = '\n '.join(
- (smart_text(os.path.realpath(path)) for path in result))
+ (smart_text(os.path.realpath(storage.path(p))) for storage, p in result))
self.stdout.write("Found '%s' here:\n %s" % (path, output))
else:
if verbosity >= 1:
15 django/contrib/staticfiles/views.py
View
@@ -12,7 +12,7 @@
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
-from django.http import Http404
+from django.http import HttpResponse, Http404
from django.views import static
from django.contrib.staticfiles import finders
@@ -35,10 +35,11 @@ def serve(request, path, document_root=None, insecure=False, **kwargs):
"debug mode or if the the --insecure "
"option of 'runserver' is used")
normalized_path = posixpath.normpath(unquote(path)).lstrip('/')
- absolute_path = finders.find(normalized_path)
- if not absolute_path:
- if path.endswith('/') or path == '':
- raise Http404("Directory indexes are not allowed here.")
+ storage_path = finders.find(normalized_path)
+ if storage_path is None:
raise Http404("'%s' could not be found" % path)
- document_root, path = os.path.split(absolute_path)
- return static.serve(request, path, document_root=document_root, **kwargs)
+ storage, relative_path = storage_path
+ if storage.isdir(relative_path):
+ raise Http404("Directory indexes are not allowed here.")
+ return HttpResponse(storage.open(relative_path))
+
128 django/core/files/storage.py
View
@@ -4,8 +4,21 @@
from urllib.parse import urljoin
except ImportError: # Python 2
from urlparse import urljoin
+import pkgutil
import itertools
from datetime import datetime
+try:
+ import pkg_resources
+except ImportError:
+ pkg_resources = None
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from StringIO import StringIO
+try:
+ import zipimport
+except ImportError:
+ zipimport = None
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
@@ -100,6 +113,12 @@ def exists(self, name):
"""
raise NotImplementedError()
+ def isdir(self, name):
+ """
+ Returns True if path is an existing directory in the storage system.
+ """
+ raise NotImplementedError()
+
def listdir(self, path):
"""
Lists the contents of the specified path, returning a 2-tuple of lists;
@@ -242,6 +261,9 @@ def delete(self, name):
def exists(self, name):
return os.path.exists(self.path(name))
+ def isdir(self, name):
+ return os.path.isdir(self.path(name))
+
def listdir(self, path):
path = self.path(path)
directories, files = [], []
@@ -276,6 +298,112 @@ def created_time(self, name):
def modified_time(self, name):
return datetime.fromtimestamp(os.path.getmtime(self.path(name)))
+class _PkgResourcesAppDirectoryStorage(Storage):
+
+ def __init__(self, app, path):
+ self.app = app
+ self.path = '/' + path.lstrip('/')
+
+ def _path(self, name):
+ return safe_join(self.path, name.lstrip('/'))[1:]
+
+ def _open(self, name, mode):
+ return File(pkg_resources.resource_stream(self.app, self._path(name)), name)
+
+ def exists(self, name):
+ return pkg_resources.resource_exists(self.app, self._path(name))
+
+ def isdir(self, name):
+ return pkg_resources.resource_isdir(self.app, self._path(name))
+
+ def listdir(self, path):
+ return pkg_resources.resource_listdir(self.app, self._path(name))
+
+class _PEP302AppDirectoryStorage(Storage):
+
+ def __init__(self, app, path):
+ self.app = app
+ self.path = '/' + path.lstrip('/')
+
+ def _path(self, name):
+ return safe_join(self.path, name.lstrip('/'))[1:]
+
+ def _open(self, name, mode):
+ data = pkgutils.get_data(self.app, self._path(name))
+ if data is not None:
+ return File(StringIO(data), name)
+ raise IOError
+
+ def isdir(self, name):
+ return True
+
+ def exists(self, name):
+ return True
+
+ def listdir(self, path):
+ return []
+
+class _ZipAppDirectoryStorage(Storage):
+
+ def __init__(self, app, loader, path):
+ self.app = app
+ self.loader = loader
+ self.path = path
+ if self.loader.prefix:
+ self.prefix = '/' + self.loader.prefix.strip('/') + '/' + self.app.replace('.', '/')
+ else:
+ self.prefix = '/' + self.app.replace('.', '/')
+ self.files = zipimport._zip_directory_cache[self.loader.archive]
+
+ def _path(self, name):
+ return safe_join(self.prefix , self.path.lstrip('/'), name.lstrip('/'))[1:]
+
+ def _open(self, name, mode):
+ return File(StringIO(self.loader.get_data(self._path(name))), name)
+
+ def isdir(self, name):
+ return self._path(name)+'/' in self.files
+
+ def exists(self, name):
+ if self.isdir(name.rstrip('/')):
+ return True
+
+ return self._path(name) in self.files
+
+ def listdir(self, path):
+ if not isdir(path):
+ raise OSError
+ path = self._path(path)
+
+ return [ name for name in self.files
+ if name.startswith(path) and
+ '/' not in name[len(path):].rstrip('/') ]
+
+class AppDirectoryStorage(LazyObject):
+
+ def __init__(self, app, path):
+ super(AppDirectoryStorage, self).__init__()
+ self.__dict__['_app'] = app
+ self.__dict__['_path'] = path
+
+ def _setup(self):
+ mod = import_module(self._app)
+ loader = pkgutil.get_loader(self._app)
+ if isinstance(loader, pkgutil.ImpLoader):
+ self._wrapped = FileSystemStorage(safe_join(mod.__path__[0], self._path))
+ return
+
+ if pkg_resources:
+ self._wrapped = _PkgResourcesAppDirectoryStorage(self._app, self._path)
+ return
+
+ if zipimport:
+ if isinstance(loader, zipimport.zipimporter):
+ self._wrapped = _ZipAppDirectoryStorage(self._app, loader, self._path)
+ return
+
+ self._wrapped = _PEP302AppDirectoryStorage(self._app, self._path)
+
def get_storage_class(import_path=None):
if import_path is None:
import_path = settings.DEFAULT_FILE_STORAGE
61 django/core/management/__init__.py
View
@@ -3,12 +3,13 @@
import sys
from optparse import OptionParser, NO_DEFAULT
import imp
+import pkgutil
import warnings
from django.core.exceptions import ImproperlyConfigured
from django.core.management.base import BaseCommand, CommandError, handle_default_options
from django.core.management.color import color_style
-from django.utils.importlib import import_module
+from django.utils.importlib import import_module, find_package_path
from django.utils import six
# For backwards compatibility: get_version() used to be in this module.
@@ -25,11 +26,11 @@ def find_commands(management_dir):
Returns an empty list if no commands are defined.
"""
- command_dir = os.path.join(management_dir, 'commands')
try:
- return [f[:-3] for f in os.listdir(command_dir)
- if not f.startswith('_') and f.endswith('.py')]
- except OSError:
+ commands_dir = find_package_path('commands', [management_dir])[0]
+ return [name for loader,name,ispkg in pkgutil.iter_modules([commands_dir])
+ if not name.startswith('_') ]
+ except ImportError:
return []
def find_management_module(app_name):
@@ -41,31 +42,39 @@ def find_management_module(app_name):
"""
parts = app_name.split('.')
parts.append('management')
- parts.reverse()
- part = parts.pop()
- path = None
-
- # When using manage.py, the project module is added to the path,
- # loaded, then removed from the path. This means that
- # testproject.testapp.models can be loaded in future, even if
- # testproject isn't in the path. When looking for the management
- # module, we need look for the case where the project name is part
- # of the app_name but the project directory itself isn't on the path.
- try:
- f, path, descr = imp.find_module(part, path)
- except ImportError as e:
- if os.path.basename(os.getcwd()) != part:
- raise e
+
+ for i in range(len(parts), 0, -1):
+ try:
+ path = sys.modules['.'.join(parts[:i])].__path__
+ except AttributeError:
+ raise ImportError("No package named %s" % parts[i-1])
+ except KeyError:
+ continue
+
+ parts = parts[i:]
+ parts.reverse()
+ break
else:
- if f:
- f.close()
+ parts.reverse()
+ part = parts.pop()
+ path = None
+
+ # When using manage.py, the project module is added to the path,
+ # loaded, then removed from the path. This means that
+ # testproject.testapp.models can be loaded in future, even if
+ # testproject isn't in the path. When looking for the management
+ # module, we need look for the case where the project name is part
+ # of the app_name but the project directory itself isn't on the path.
+ try:
+ path = find_package_path(part, path)
+ except ImportError as e:
+ if os.path.basename(os.getcwd()) != part:
+ raise e
while parts:
part = parts.pop()
- f, path, descr = imp.find_module(part, path and [path] or None)
- if f:
- f.close()
- return path
+ path = find_package_path(part, path)
+ return path[0]
def load_command_class(app_name, name):
"""
91 django/core/management/commands/loaddata.py
View
@@ -7,6 +7,7 @@
from django.conf import settings
from django.core import serializers
+from django.core.files.storage import FileSystemStorage, AppDirectoryStorage
from django.core.management.base import BaseCommand, CommandError
from django.core.management.color import no_style
from django.db import (connections, router, transaction, DEFAULT_DB_ALIAS,
@@ -77,37 +78,55 @@ def handle(self, *fixture_labels, **options):
transaction.managed(True, using=self.using)
class SingleZipReader(zipfile.ZipFile):
- def __init__(self, *args, **kwargs):
- zipfile.ZipFile.__init__(self, *args, **kwargs)
+ def __init__(self, storage, path, mode, *args, **kwargs):
+ fileobj = storage.open(path, mode)
+ zipfile.ZipFile.__init__(self, fileobj, *args, **kwargs)
if settings.DEBUG:
assert len(self.namelist()) == 1, "Zip-compressed fixtures must contain only one file."
def read(self):
return zipfile.ZipFile.read(self, self.namelist()[0])
+ class GzipFileReader(gzip.GzipFile):
+ def __init__(self, storage, path, mode, *args, **kwargs):
+ fileobj = storage.open(path, mode)
+ gzip.GzipFile.__init__(self, fileobj, *args, **kwargs)
+
+ class _BZ2FileReader(object):
+ def __init__(self, storage, path, mode):
+ self.fileobj = storage.open(path, mode)
+
+ def read(self):
+ return bz2.BZ2Decompressor(self.fileobj.read())
+
+ def close(self):
+ self.fileobj.close()
+
+ def BZ2FileReader(storage, path, mode):
+ try:
+ absolute_path = storage.path(path)
+ return bz2.BZ2File(absolute_path, mode=mode)
+ except NotImplementedError:
+ return _BZ2FileReader(storage, path, mode)
+
+
self.compression_types = {
- None: open,
- 'gz': gzip.GzipFile,
+ None: lambda storage, path, mode: storage.open(path, mode),
+ 'gz': GzipFileReader,
'zip': SingleZipReader
}
if has_bz2:
- self.compression_types['bz2'] = bz2.BZ2File
+ self.compression_types['bz2'] = BZ2FileReader
- app_module_paths = []
+ app_fixture_storages = []
for app in get_apps():
- if hasattr(app, '__path__'):
- # It's a 'models/' subpackage
- for path in app.__path__:
- app_module_paths.append(path)
- else:
- # It's a models.py module
- app_module_paths.append(app.__file__)
-
- app_fixtures = [os.path.join(os.path.dirname(path), 'fixtures') for path in app_module_paths]
+ storage = AppDirectoryStorage(app.__name__[:-7], 'fixtures')
+ if storage.isdir(''):
+ app_fixture_storages.append(storage)
try:
with connection.constraint_checks_disabled():
for fixture_label in fixture_labels:
- self.load_label(fixture_label, app_fixtures)
+ self.load_label(fixture_label, app_fixture_storages)
# Since we disabled constraint checks, we must manually check for
# any invalid keys that might have been added
@@ -155,7 +174,7 @@ def read(self):
if commit:
connection.close()
- def load_label(self, fixture_label, app_fixtures):
+ def load_label(self, fixture_label, app_fixture_storages):
parts = fixture_label.split('.')
@@ -184,21 +203,22 @@ def load_label(self, fixture_label, app_fixtures):
(fixture_name, format))
if os.path.isabs(fixture_name):
- fixture_dirs = [fixture_name]
+ fixture_storages = [FileSystemStorage(fixture_name)]
else:
- fixture_dirs = app_fixtures + list(settings.FIXTURE_DIRS) + ['']
+ fixture_storages = app_fixture_storages + list(map(FileSystemStorage, settings.FIXTURE_DIRS)) + [FileSystemStorage('')]
- for fixture_dir in fixture_dirs:
- self.process_dir(fixture_dir, fixture_name, compression_formats,
+ for fixture_storage in fixture_storages:
+ self.process_storage(fixture_storage, fixture_name, compression_formats,
formats)
- def process_dir(self, fixture_dir, fixture_name, compression_formats,
+ def process_storage(self, fixture_storage, fixture_name, compression_formats,
serialization_formats):
- humanize = lambda dirname: "'%s'" % dirname if dirname else 'absolute path'
+ # humanize = lambda dirname: "'%s'" % dirname if dirname else 'absolute path'
if self.verbosity >= 2:
- self.stdout.write("Checking %s for fixtures..." % humanize(fixture_dir))
+ # self.stdout.write("Checking %s for fixtures..." % humanize(fixture_dir))
+ self.stdout.write("Checking %s for fixtures..." % str(fixture_storage))
label_found = False
for combo in product([self.using, None], serialization_formats, compression_formats):
@@ -211,28 +231,36 @@ def process_dir(self, fixture_dir, fixture_name, compression_formats,
)
if self.verbosity >= 3:
+ # self.stdout.write("Trying %s for %s fixture '%s'..." % \
+ # (humanize(fixture_dir), file_name, fixture_name))
self.stdout.write("Trying %s for %s fixture '%s'..." % \
- (humanize(fixture_dir), file_name, fixture_name))
- full_path = os.path.join(fixture_dir, file_name)
+ (str(fixture_storage), file_name, fixture_name))
+
open_method = self.compression_types[compression_format]
try:
- fixture = open_method(full_path, 'r')
+ fixture = open_method(fixture_storage, file_name, 'r')
except IOError:
if self.verbosity >= 2:
+ # self.stdout.write("No %s fixture '%s' in %s." % \
+ # (format, fixture_name, humanize(fixture_dir)))
self.stdout.write("No %s fixture '%s' in %s." % \
- (format, fixture_name, humanize(fixture_dir)))
+ (format, fixture_name, str(fixture_storage)))
else:
try:
if label_found:
+ # raise CommandError("Multiple fixtures named '%s' in %s. Aborting." %
+ # (fixture_name, humanize(fixture_dir)))
raise CommandError("Multiple fixtures named '%s' in %s. Aborting." %
- (fixture_name, humanize(fixture_dir)))
+ (fixture_name, str(fixture_storage)))
self.fixture_count += 1
objects_in_fixture = 0
loaded_objects_in_fixture = 0
if self.verbosity >= 2:
+ # self.stdout.write("Installing %s fixture '%s' from %s." % \
+ # (format, fixture_name, humanize(fixture_dir)))
self.stdout.write("Installing %s fixture '%s' from %s." % \
- (format, fixture_name, humanize(fixture_dir)))
+ (format, fixture_name, str(fixture_storage)))
objects = serializers.deserialize(format, fixture, using=self.using, ignorenonexistent=self.ignore)
@@ -257,7 +285,8 @@ def process_dir(self, fixture_dir, fixture_name, compression_formats,
label_found = True
except Exception as e:
if not isinstance(e, CommandError):
- e.args = ("Problem installing fixture '%s': %s" % (full_path, e),)
+ # e.args = ("Problem installing fixture '%s': %s" % (full_path, e),)
+ e.args = ("Problem installing fixture '%s': %s" % (str(fixture_storage)+file_name, e),)
raise
finally:
fixture.close()
12 django/db/utils.py
View
@@ -1,6 +1,7 @@
import os
import pkgutil
from threading import local
+import pkgutil
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
@@ -27,13 +28,10 @@ def load_backend(backend_name):
except ImportError as e_user:
# The database backend wasn't found. Display a helpful error message
# listing all possible (built-in) database backends.
- backend_dir = os.path.join(os.path.dirname(__file__), 'backends')
- try:
- builtin_backends = [
- name for _, name, ispkg in pkgutil.iter_modules([backend_dir])
- if ispkg and name != 'dummy']
- except EnvironmentError:
- builtin_backends = []
+ backend_dir = import_module('django.db.backends').__path__
+ builtin_backends = [
+ name for _, name, ispkg in pkgutil.iter_modules([backend_dir])
+ if ispkg and name != 'dummy']
if backend_name not in ['django.db.backends.%s' % b for b in
builtin_backends]:
backend_reprs = map(repr, sorted(builtin_backends))
34 django/template/loader.py
View
@@ -3,10 +3,9 @@
# This uses the TEMPLATE_LOADERS setting, which is a list of loaders to use.
# Each loader is expected to have this interface:
#
-# callable(name, dirs=[])
+# callable(name)
#
# name is the template name.
-# dirs is an optional list of directories to search instead of TEMPLATE_DIRS.
#
# The loader should return a tuple of (template_source, path). The path returned
# might be shown to the user for debugging purposes, so it should identify where
@@ -36,15 +35,12 @@
class BaseLoader(object):
is_usable = False
- def __init__(self, *args, **kwargs):
- pass
-
- def __call__(self, template_name, template_dirs=None):
- return self.load_template(template_name, template_dirs)
+ def __call__(self, template_name):
+ return self.load_template(template_name)
- def load_template(self, template_name, template_dirs=None):
- source, display_name = self.load_template_source(template_name, template_dirs)
- origin = make_origin(display_name, self.load_template_source, template_name, template_dirs)
+ def load_template(self, template_name):
+ source, display_name = self.load_template_source(template_name)
+ origin = make_origin(display_name, self.load_template_source, template_name)
try:
template = get_template_from_string(source, origin, template_name)
return template, None
@@ -55,7 +51,7 @@ def load_template(self, template_name, template_dirs=None):
# not exist.
return source, display_name
- def load_template_source(self, template_name, template_dirs=None):
+ def load_template_source(self, template_name):
"""
Returns a tuple containing the source and origin for the given template
name.
@@ -72,16 +68,16 @@ def reset(self):
pass
class LoaderOrigin(Origin):
- def __init__(self, display_name, loader, name, dirs):
+ def __init__(self, display_name, loader, name):
super(LoaderOrigin, self).__init__(display_name)
- self.loader, self.loadname, self.dirs = loader, name, dirs
+ self.loader, self.loadname = loader, name
def reload(self):
- return self.loader(self.loadname, self.dirs)[0]
+ return self.loader(self.loadname)[0]
-def make_origin(display_name, loader, name, dirs):
+def make_origin(display_name, loader, name):
if settings.TEMPLATE_DEBUG and display_name:
- return LoaderOrigin(display_name, loader, name, dirs)
+ return LoaderOrigin(display_name, loader, name)
else:
return None
@@ -118,7 +114,7 @@ def find_template_loader(loader):
else:
raise ImproperlyConfigured('Loader does not define a "load_template" callable template source loader')
-def find_template(name, dirs=None):
+def find_template(name):
# Calculate template_source_loaders the first time the function is executed
# because putting this logic in the module-level namespace may cause
# circular import errors. See Django ticket #1292.
@@ -132,8 +128,8 @@ def find_template(name, dirs=None):
template_source_loaders = tuple(loaders)
for loader in template_source_loaders:
try:
- source, display_name = loader(name, dirs)
- return (source, make_origin(display_name, loader, name, dirs))
+ source, display_name = loader(name)
+ return (source, make_origin(display_name, loader, name))
except TemplateDoesNotExist:
pass
raise TemplateDoesNotExist(name)
66 django/template/loaders/app_directories.py
View
@@ -8,58 +8,34 @@
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
+from django.core.files.storage import AppDirectoryStorage
from django.template.base import TemplateDoesNotExist
from django.template.loader import BaseLoader
-from django.utils._os import safe_join
-from django.utils.importlib import import_module
-from django.utils import six
-# At compile time, cache the directories to search.
-if not six.PY3:
- fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
-app_template_dirs = []
-for app in settings.INSTALLED_APPS:
- try:
- mod = import_module(app)
- except ImportError as e:
- raise ImproperlyConfigured('ImportError %s: %s' % (app, e.args[0]))
- template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
- if os.path.isdir(template_dir):
- if not six.PY3:
- template_dir = template_dir.decode(fs_encoding)
- app_template_dirs.append(template_dir)
-# It won't change, so convert it to a tuple to save memory.
-app_template_dirs = tuple(app_template_dirs)
class Loader(BaseLoader):
is_usable = True
- def get_template_sources(self, template_name, template_dirs=None):
- """
- Returns the absolute paths to "template_name", when appended to each
- directory in "template_dirs". Any paths that don't lie inside one of the
- template dirs are excluded from the result set, for security reasons.
- """
- if not template_dirs:
- template_dirs = app_template_dirs
- for template_dir in template_dirs:
- try:
- yield safe_join(template_dir, template_name)
- except UnicodeDecodeError:
- # The template dir name was a bytestring that wasn't valid UTF-8.
- raise
- except ValueError:
- # The joined path was located outside of template_dir.
- pass
+ def __init__(self, apps=None):
+ self.apps = apps
+ if apps is None:
+ self.apps = settings.INSTALLED_APPS
+ self.reset()
- def load_template_source(self, template_name, template_dirs=None):
- for filepath in self.get_template_sources(template_name, template_dirs):
- try:
- with open(filepath, 'rb') as fp:
- return (fp.read().decode(settings.FILE_CHARSET), filepath)
- except IOError:
- pass
- raise TemplateDoesNotExist(template_name)
+ def reset(self):
+ app_template_storages = []
+ for app in self.apps:
+ storage = AppDirectoryStorage(app, 'templates')
+ if storage.isdir(''):
+ app_template_storages.append(storage)
+
+ self.app_template_storages = tuple(app_template_storages)
-_loader = Loader()
+ def load_template_source(self, template_name):
+ for storage in self.app_template_storages:
+ if storage.exists(template_name):
+ with storage.open(template_name, 'rb') as fp:
+ return (fp.read().decode(settings.FILE_CHARSET), template_name)
+
+ raise TemplateDoesNotExist(template_name)
13 django/template/loaders/cached.py
View
@@ -27,23 +27,20 @@ def loaders(self):
self._cached_loaders = cached_loaders
return self._cached_loaders
- def find_template(self, name, dirs=None):
+ def find_template(self, name):
for loader in self.loaders:
try:
- template, display_name = loader(name, dirs)
- return (template, make_origin(display_name, loader, name, dirs))
+ template, display_name = loader(name)
+ return (template, make_origin(display_name, loader, name))
except TemplateDoesNotExist:
pass
raise TemplateDoesNotExist(name)
- def load_template(self, template_name, template_dirs=None):
+ def load_template(self, template_name):
key = template_name
- if template_dirs:
- # If template directories were specified, use a hash to differentiate
- key = '-'.join([template_name, hashlib.sha1('|'.join(template_dirs)).hexdigest()])
if key not in self.template_cache:
- template, origin = self.find_template(template_name, template_dirs)
+ template, origin = self.find_template(template_name)
if not hasattr(template, 'render'):
try:
template = get_template_from_string(template, origin, template_name)
35 django/template/loaders/eggs.py
View
@@ -1,35 +0,0 @@
-# Wrapper for loading templates from eggs via pkg_resources.resource_string.
-from __future__ import unicode_literals
-
-try:
- from pkg_resources import resource_string
-except ImportError:
- resource_string = None
-
-from django.conf import settings
-from django.template.base import TemplateDoesNotExist
-from django.template.loader import BaseLoader
-from django.utils import six
-
-class Loader(BaseLoader):
- is_usable = resource_string is not None
-
- def load_template_source(self, template_name, template_dirs=None):
- """
- Loads templates from Python eggs via pkg_resource.resource_string.
-
- For every installed app, it tries to get the resource (app, template_name).
- """
- if resource_string is not None:
- pkg_name = 'templates/' + template_name
- for app in settings.INSTALLED_APPS:
- try:
- resource = resource_string(app, pkg_name)
- except Exception:
- continue
- if not six.PY3:
- resource = resource.decode(settings.FILE_CHARSET)
- return (resource, 'egg:%s:%s' % (app, pkg_name))
- raise TemplateDoesNotExist(template_name)
-
-_loader = Loader()
17 django/template/loaders/filesystem.py
View
@@ -10,15 +10,18 @@
class Loader(BaseLoader):
is_usable = True
- def get_template_sources(self, template_name, template_dirs=None):
+ def __init__(self, template_dirs=None):
+ self.template_dirs = template_dirs
+ if template_dirs is None:
+ self.template_dirs = settings.TEMPLATE_DIRS
+
+ def get_template_sources(self, template_name):
"""
Returns the absolute paths to "template_name", when appended to each
directory in "template_dirs". Any paths that don't lie inside one of the
template dirs are excluded from the result set, for security reasons.
"""
- if not template_dirs:
- template_dirs = settings.TEMPLATE_DIRS
- for template_dir in template_dirs:
+ for template_dir in self.template_dirs:
try:
yield safe_join(template_dir, template_name)
except UnicodeDecodeError:
@@ -30,9 +33,9 @@ def get_template_sources(self, template_name, template_dirs=None):
# fatal).
pass
- def load_template_source(self, template_name, template_dirs=None):
+ def load_template_source(self, template_name):
tried = []
- for filepath in self.get_template_sources(template_name, template_dirs):
+ for filepath in self.get_template_sources(template_name):
try:
with open(filepath, 'rb') as fp:
return (fp.read().decode(settings.FILE_CHARSET), filepath)
@@ -44,5 +47,3 @@ def load_template_source(self, template_name, template_dirs=None):
error_msg = "Your TEMPLATE_DIRS setting is empty. Change it to point to at least one template directory."
raise TemplateDoesNotExist(error_msg)
load_template_source.is_usable = True
-
-_loader = Loader()
87 django/utils/importlib.py
View
@@ -1,5 +1,9 @@
# Taken from Python 2.7 with permission from/by the original author.
+import os
import sys
+import imp
+import pkgutil
+import warnings
def _resolve_name(name, package, level):
"""Return the absolute name of the module to be imported."""
@@ -34,3 +38,86 @@ def import_module(name, package=None):
name = _resolve_name(name[level:], package, level)
__import__(name)
return sys.modules[name]
+
+
+def find_package_path(name, path=None):
+ """Finds search path for package with given name.
+
+ The 'path' argument defaults to ``sys.path``.
+
+ Raises ImportError if no search path could be found.
+ """
+ if path is None:
+ path = sys.path
+
+ results = []
+
+ for path_item in path:
+ importer = get_importer(path_item)
+
+ if importer is None:
+ continue
+
+ try:
+ loader = importer.find_module(name)
+
+ if loader is not None:
+
+ if not hasattr(loader, 'is_package'):
+ warnings.warn(
+ "Django cannot find search path for package '%s' ",
+ "under '%s', because the loader returned by '%s' does ",
+ "not implement 'is_package' method."%(
+ name,
+ path_item,
+ importer.__class__.__name__))
+ continue
+
+ if not hasattr(loader, 'get_filename'):
+ warnings.warn(
+ "Django cannot find search path for package '%s' ",
+ "under '%s', because the loader returned by '%s' does ",
+ "not implement 'get_filename' method."%(
+ name,
+ path_item,
+ importer.__class__.__name__))
+ continue
+
+ if loader.is_package(name):
+ results.append(os.path.dirname(loader.get_filename(name)))
+ except ImportError:
+ pass
+
+ if not results:
+ raise ImportError("No package named %s" % name)
+
+ return results
+
+
+get_importer = pkgutil.get_importer
+
+try:
+ import zipimport
+
+ if hasattr(zipimport.zipimporter, 'get_filename'):
+ class ZipImporter(zipimport.zipimporter):
+ def get_filename(self, fullname):
+ archivepath = os.path.join(self.archive, self.prefix)
+ if self.is_package(fullname):
+ return os.path.join(archivepath, fullname, '__init__.py')
+
+ return os.path.join(archivepath, fullname + '.py')
+
+ def get_importer(path_item):
+ importer = pkgutil.get_importer(path_item)
+
+ if isinstance(importer, zipimport.zipimporter):
+ archivepath = os.path.join(importer.archive, importer.prefix)
+ importer = ZipImporter(os.path.dirname(archivepath))
+
+ return importer
+
+except ImportError:
+ pass
+
+
37 django/utils/translation/trans_real.py
View
@@ -8,13 +8,13 @@
import gettext as gettext_module
from threading import local
+from django.core.files.storage import FileSystemStorage, AppDirectoryStorage
from django.utils.importlib import import_module
from django.utils.encoding import force_str, force_text
from django.utils.safestring import mark_safe, SafeData
from django.utils import six
from django.utils.six import StringIO
-
# Translations are cached in a dictionary for every language+app tuple.
# The active translations are stored by threadid to make them thread local.
_translations = {}
@@ -109,7 +109,7 @@ def translation(language):
from django.conf import settings
- globalpath = os.path.join(os.path.dirname(sys.modules[settings.__module__].__file__), 'locale')
+ globalstorage = FileSystemStorage(os.path.join(os.path.dirname(sys.modules[settings.__module__].__file__), 'locale'))
def _fetch(lang, fallback=None):
@@ -121,15 +121,21 @@ def _fetch(lang, fallback=None):
loc = to_locale(lang)
- def _translation(path):
- try:
- t = gettext_module.translation('django', path, [loc], DjangoTranslation)
- t.set_language(lang)
- return t
- except IOError:
+ def _translation(storage):
+ nelangs = gettext_module._expand_lang(loc)
+ for nelang in nelangs:
+ locpath = os.path.join(nelang, 'LC_MESSAGES', 'django.mo')
+ if storage.exists(locpath) and not storage.isdir(locpath):
+ fp = storage.open(locpath)
+ t = DjangoTranslation(fp)
+ break
+ else:
return None
- res = _translation(globalpath)
+ t.set_language(lang)
+ return t
+
+ res = _translation(globalstorage)
# We want to ensure that, for example, "en-gb" and "en-us" don't share
# the same translation object (thus, merging en-us with a local update
@@ -140,8 +146,8 @@ def _translation(path):
res._info = res._info.copy()
res._catalog = res._catalog.copy()
- def _merge(path):
- t = _translation(path)
+ def _merge(storage):
+ t = _translation(storage)
if t is not None:
if res is None:
return t
@@ -150,15 +156,14 @@ def _merge(path):
return res
for appname in reversed(settings.INSTALLED_APPS):
- app = import_module(appname)
- apppath = os.path.join(os.path.dirname(app.__file__), 'locale')
+ appstorage = AppDirectoryStorage(appname, 'locale')
- if os.path.isdir(apppath):
- res = _merge(apppath)
+ if appstorage.isdir(''):
+ res = _merge(appstorage)
for localepath in reversed(settings.LOCALE_PATHS):
if os.path.isdir(localepath):
- res = _merge(localepath)
+ res = _merge(FileSystemStorage(localepath))
if res is None:
if fallback is not None:
4 docs/ref/templates/api.txt
View
@@ -828,8 +828,8 @@ of the ``load_template_source()`` method implemented there::
class Loader(app_directories.Loader):
is_usable = True
- def load_template(self, template_name, template_dirs=None):
- source, origin = self.load_template_source(template_name, template_dirs)
+ def load_template(self, template_name):
+ source, origin = self.load_template_source(template_name)
template = Template(source)
return template, origin
0  tests/regressiontests/admin_scripts/lib1/nons_app/__init__.py
View
No changes.
0  tests/regressiontests/admin_scripts/lib1/nons_app/management/__init__.py
View
No changes.
0  tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/__init__.py
View
No changes.
9 tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/nons_app_command1.py
View
@@ -0,0 +1,9 @@
+from django.core.management.base import BaseCommand
+
+class Command(BaseCommand):
+ help = 'Test managment commands in non-namespaced app'
+ requires_model_validation = False
+ args = ''
+
+ def handle(self, *labels, **options):
+ print 'EXECUTE:nons_app_command1'
0  tests/regressiontests/admin_scripts/lib1/nons_app/models.py
View
No changes.
0  tests/regressiontests/admin_scripts/lib1/npapp/__init__.py
View
No changes.
0  tests/regressiontests/admin_scripts/lib1/npapp/management.py
View
No changes.
0  tests/regressiontests/admin_scripts/lib1/npapp/models.py
View
No changes.
6 tests/regressiontests/admin_scripts/lib1/nsapps/__init__.py
View
@@ -0,0 +1,6 @@
+# http://packages.python.org/distribute/setuptools.html#namespace-packages
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
6 tests/regressiontests/admin_scripts/lib1/nsapps/contrib/__init__.py
View
@@ -0,0 +1,6 @@
+# http://packages.python.org/distribute/setuptools.html#namespace-packages
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
0  tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/__init__.py
View
No changes.
0  tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/__init__.py
View
No changes.
0  tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/__init__.py
View
No changes.
9 tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/app1_command1.py
View
@@ -0,0 +1,9 @@
+from django.core.management.base import BaseCommand
+
+class Command(BaseCommand):
+ help = 'Test managment commands in namespaced apps'
+ requires_model_validation = False
+ args = ''
+
+ def handle(self, *labels, **options):
+ print 'EXECUTE:app1_command1'
0  tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/models.py
View
No changes.
6 tests/regressiontests/admin_scripts/lib2/nsapps/__init__.py
View
@@ -0,0 +1,6 @@
+# http://packages.python.org/distribute/setuptools.html#namespace-packages
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
6 tests/regressiontests/admin_scripts/lib2/nsapps/contrib/__init__.py
View
@@ -0,0 +1,6 @@
+# http://packages.python.org/distribute/setuptools.html#namespace-packages
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
0  tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/__init__.py
View
No changes.
0  tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/__init__.py
View
No changes.
0  tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/__init__.py
View
No changes.
9 tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/app2_command1.py
View
@@ -0,0 +1,9 @@
+from django.core.management.base import BaseCommand
+
+class Command(BaseCommand):
+ help = 'Test managment commands in namespaced apps'
+ requires_model_validation = False
+ args = ''
+
+ def handle(self, *labels, **options):
+ print 'EXECUTE:app2_command1'
0  tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/models.py
View
No changes.
1  tests/regressiontests/admin_scripts/lib3/_addsitedir.py
View
@@ -0,0 +1 @@
+import os.path, site; site.addsitedir(os.path.dirname(__file__))
1  tests/regressiontests/admin_scripts/lib3/egg_module.pth
View
@@ -0,0 +1 @@
+test_egg.egg
1  tests/regressiontests/admin_scripts/lib3/exapps-nspkg.pth
View
@@ -0,0 +1 @@
+import 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)
0  tests/regressiontests/admin_scripts/lib3/exapps/app3/__init__.py
View
No changes.
0  tests/regressiontests/admin_scripts/lib3/exapps/app3/management/__init__.py
View
No changes.
0  tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/__init__.py
View
No changes.
9 tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/app3_command1.py
View
@@ -0,0 +1,9 @@
+from django.core.management.base import BaseCommand
+
+class Command(BaseCommand):
+ help = 'Test managment commands in namespaced apps'
+ requires_model_validation = False
+ args = ''
+
+ def handle(self, *labels, **options):
+ print 'EXECUTE:app3_command1'
0  tests/regressiontests/admin_scripts/lib3/exapps/app3/models.py
View
No changes.
BIN  tests/regressiontests/admin_scripts/lib3/test_egg.egg
View
Binary file not shown
100 tests/regressiontests/admin_scripts/tests.py
View
@@ -96,6 +96,10 @@ def _ext_backend_paths(self):
def run_test(self, script, args, settings_file=None, apps=None):
project_dir = os.path.dirname(test_dir)
base_dir = os.path.dirname(project_dir)
+ lib1_dir = os.path.join(os.path.dirname(__file__), 'lib1')
+ lib2_dir = os.path.join(os.path.dirname(__file__), 'lib2')
+ lib3_dir = os.path.join(os.path.dirname(__file__), 'lib3')
+ eggs_dir = os.path.join(os.path.dirname(__file__), 'eggs')
ext_backend_base_dirs = self._ext_backend_paths()
# Remember the old environment
@@ -113,7 +117,7 @@ def run_test(self, script, args, settings_file=None, apps=None):
os.environ['DJANGO_SETTINGS_MODULE'] = settings_file
elif 'DJANGO_SETTINGS_MODULE' in os.environ:
del os.environ['DJANGO_SETTINGS_MODULE']
- python_path = [project_dir, base_dir]
+ python_path = [project_dir, base_dir, lib1_dir, lib2_dir, lib3_dir]
python_path.extend(ext_backend_base_dirs)
os.environ[python_path_var_name] = os.pathsep.join(python_path)
@@ -1613,3 +1617,97 @@ def test_basic(self):
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "FOO = 'bar' ###")
+
+
+class NamespacePackagedApps(AdminScriptTestCase):
+ def setUp(self):
+ self.write_settings('settings.py', apps=['nons_app', 'nsapps.contrib.app1','nsapps.contrib.app2','exapps.app3', 'egg_module'])
+ settings_file = open(os.path.join(test_dir, 'settings.py'), 'a')
+ settings_file.write('import _addsitedir')
+ settings_file.close()
+
+ def tearDown(self):
+ self.remove_settings('settings.py')
+
+ def test_help(self):
+ out, err = self.run_manage(['help'])
+ self.assertNoOutput(err)
+ self.assertOutput(out, "nons_app_command1")
+ self.assertOutput(out, "app1_command1")
+ self.assertOutput(out, "app2_command1")
+ self.assertOutput(out, "app3_command1")
+ self.assertOutput(out, "egg_command")
+
+ def test_nons_app(self):
+ args = ['nons_app_command1']
+ out, err = self.run_manage(args)
+ self.assertNoOutput(err)
+ self.assertOutput(out, "EXECUTE:nons_app_command1")
+
+ def test_nsapps(self):
+ args = ['app1_command1']
+ out, err = self.run_manage(args)
+ self.assertNoOutput(err)
+ self.assertOutput(out, "EXECUTE:app1_command1")
+
+ args = ['app2_command1']
+ out, err = self.run_manage(args)
+ self.assertNoOutput(err)
+ self.assertOutput(out, "EXECUTE:app2_command1")
+
+ def test_exapps(self):
+ args = ['app3_command1']
+ out, err = self.run_manage(args)
+ self.assertNoOutput(err)
+ self.assertOutput(out, "EXECUTE:app3_command1")
+
+ def test_exapps(self):
+ args = ['egg_command']
+ out, err = self.run_manage(args)
+ self.assertNoOutput(err)
+ self.assertOutput(out, "EXECUTE:egg_command")
+
+
+class PreloadedNamespacePackagedApps(AdminScriptTestCase):
+ def setUp(self):
+ self.write_settings('settings.py', apps=['nsapps.contrib.app1','nsapps.contrib.app2'])
+ settings_file = open(os.path.join(test_dir, 'settings.py'), 'a')
+ settings_file.write('import nsapps')
+ settings_file.close()
+
+ def tearDown(self):
+ self.remove_settings('settings.py')
+
+ def test_help(self):
+ out, err = self.run_manage(['help'])
+ self.assertNoOutput(err)
+ self.assertOutput(out, "app1_command1")
+ self.assertOutput(out, "app2_command1")
+
+ def test_nsapps(self):
+ args = ['app1_command1']
+ out, err = self.run_manage(args)
+ self.assertNoOutput(err)
+ self.assertOutput(out, "EXECUTE:app1_command1")
+
+ args = ['app2_command1']
+ out, err = self.run_manage(args)
+ self.assertNoOutput(err)
+ self.assertOutput(out, "EXECUTE:app2_command1")
+
+
+class NonPackageManagementApps(AdminScriptTestCase):
+ def setUp(self):
+ self.write_settings('settings.py', apps=['npapp'])
+ settings_file = open(os.path.join(test_dir, 'settings.py'), 'a')
+ settings_file.write('import npapp.management')
+ settings_file.close()
+
+ def tearDown(self):
+ self.remove_settings('settings.py')
+
+ def test_help(self):
+ out, err = self.run_manage(['help'])
+ self.assertNoOutput(err)
+
+
BIN  tests/regressiontests/i18n/eggs/localeegg.egg
View
Binary file not shown
28 tests/regressiontests/i18n/tests.py
View
@@ -4,6 +4,7 @@
import datetime
import decimal
import os
+import sys
import pickle
from threading import local
@@ -880,6 +881,33 @@ def test_locale_paths_override_app_translation(self):
with self.settings(INSTALLED_APPS=extended_apps):
self.assertUgettext('Time', 'LOCALE_PATHS')
+class EggResolutionOrderI18NTests(ResolutionOrderI18NTests):
+
+ def setUp(self):
+ self.old_path = sys.path[:]
+ self.egg_dir = '%s/eggs' % os.path.dirname(__file__)
+ egg_name = '%s/localeegg.egg' % self.egg_dir
+ sys.path.insert(0, egg_name)
+ super(EggResolutionOrderI18NTests, self).setUp()
+
+ def tearDown(self):
+ super(EggResolutionOrderI18NTests, self).tearDown()
+ sys.path = self.old_path
+
+class EggAppResolutionOrderI18NTests(EggResolutionOrderI18NTests):
+
+ def setUp(self):
+ self.old_installed_apps = settings.INSTALLED_APPS
+ settings.INSTALLED_APPS = ['resolution'] + list(settings.INSTALLED_APPS)
+ super(EggAppResolutionOrderI18NTests, self).setUp()
+
+ def tearDown(self):
+ settings.INSTALLED_APPS = self.old_installed_apps
+ super(EggAppResolutionOrderI18NTests, self).tearDown()
+
+ def test_app_translation(self):
+ self.assertUgettext('Date/time', 'APP')
+
class DjangoFallbackResolutionOrderI18NTests(ResolutionOrderI18NTests):
def test_django_fallback(self):
6 tests/regressiontests/staticfiles_tests/tests.py
View
@@ -655,13 +655,13 @@ class FinderTestCase(object):
"""
def test_find_first(self):
src, dst = self.find_first
- found = self.finder.find(src)
- self.assertEqual(os.path.normcase(found), os.path.normcase(dst))
+ storage, path = self.finder.find(src)
+ self.assertEqual(os.path.normcase(storage.path(path)), os.path.normcase(dst))
def test_find_all(self):
src, dst = self.find_all
found = self.finder.find(src, all=True)
- found = [os.path.normcase(f) for f in found]
+ found = [os.path.normcase(storage.path(path)) for storage, path in found]
dst = [os.path.normcase(d) for d in dst]
self.assertEqual(found, dst)
6 tests/regressiontests/templates/loaders.py
View
@@ -15,7 +15,7 @@
import os.path
from django.template import TemplateDoesNotExist, Context
-from django.template.loaders.eggs import Loader as EggLoader
+from django.template.loaders.app_directories import Loader as EggLoader
from django.template import loader
from django.utils import unittest, six
from django.utils.six import StringIO
@@ -30,8 +30,8 @@ def __init__(self, module):
def _has(self, path):
return path in self.module._resources
- def _isdir(self, path):
- return False
+ def _isdir(self,path):
+ return path == 'templates'
def get_resource_stream(self, manager, resource_name):
return self.module._resources[resource_name]
16 tests/regressiontests/templates/tests.py
View
@@ -160,20 +160,16 @@ def __str__(self):
class Templates(TestCase):
def test_loaders_security(self):
- ad_loader = app_directories.Loader()
- fs_loader = filesystem.Loader()
def test_template_sources(path, template_dirs, expected_sources):
if isinstance(expected_sources, list):
# Fix expected sources so they are abspathed
expected_sources = [os.path.abspath(s) for s in expected_sources]
- # Test the two loaders (app_directores and filesystem).
- func1 = lambda p, t: list(ad_loader.get_template_sources(p, t))
- func2 = lambda p, t: list(fs_loader.get_template_sources(p, t))
- for func in (func1, func2):
- if isinstance(expected_sources, list):
- self.assertEqual(func(path, template_dirs), expected_sources)
- else:
- self.assertRaises(expected_sources, func, path, template_dirs)
+ # Test filesystem loader.
+ func = lambda p, t: list(filesystem.Loader(t).get_template_sources(p))
+ if isinstance(expected_sources, list):
+ self.assertEqual(func(path, template_dirs), expected_sources)
+ else:
+ self.assertRaises(expected_sources, func, path, template_dirs)
template_dirs = ['/dir1', '/dir2']
test_template_sources('index.html', template_dirs,

No commit comments for this range

Something went wrong with that request. Please try again.