Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: bhuztez/django
...
head fork: bhuztez/django
Checking mergeability… Don't worry, you can still create the pull request.
  • 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
View
175 django/contrib/staticfiles/finders.py
@@ -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
View
4 django/contrib/staticfiles/management/commands/findstatic.py
@@ -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:
View
15 django/contrib/staticfiles/views.py
@@ -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))
+
View
128 django/core/files/storage.py
@@ -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
View
61 django/core/management/__init__.py
@@ -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):
"""
View
91 django/core/management/commands/loaddata.py
@@ -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()
View
12 django/db/utils.py
@@ -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))
View
34 django/template/loader.py
@@ -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)
View
66 django/template/loaders/app_directories.py
@@ -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)
View
13 django/template/loaders/cached.py
@@ -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)
View
35 django/template/loaders/eggs.py
@@ -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()
View
17 django/template/loaders/filesystem.py
@@ -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()
View
87 django/utils/importlib.py
@@ -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
+
+
View
37 django/utils/translation/trans_real.py
@@ -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:
View
4 docs/ref/templates/api.txt
@@ -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
View
0  tests/regressiontests/admin_scripts/lib1/nons_app/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/lib1/nons_app/management/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/__init__.py
No changes.
View
9 tests/regressiontests/admin_scripts/lib1/nons_app/management/commands/nons_app_command1.py
@@ -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'
View
0  tests/regressiontests/admin_scripts/lib1/nons_app/models.py
No changes.
View
0  tests/regressiontests/admin_scripts/lib1/npapp/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/lib1/npapp/management.py
No changes.
View
0  tests/regressiontests/admin_scripts/lib1/npapp/models.py
No changes.
View
6 tests/regressiontests/admin_scripts/lib1/nsapps/__init__.py
@@ -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__)
View
6 tests/regressiontests/admin_scripts/lib1/nsapps/contrib/__init__.py
@@ -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__)
View
0  tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/__init__.py
No changes.
View
9 tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/management/commands/app1_command1.py
@@ -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'
View
0  tests/regressiontests/admin_scripts/lib1/nsapps/contrib/app1/models.py
No changes.
View
6 tests/regressiontests/admin_scripts/lib2/nsapps/__init__.py
@@ -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__)
View
6 tests/regressiontests/admin_scripts/lib2/nsapps/contrib/__init__.py
@@ -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__)
View
0  tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/__init__.py
No changes.
View
9 tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/management/commands/app2_command1.py
@@ -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'
View
0  tests/regressiontests/admin_scripts/lib2/nsapps/contrib/app2/models.py
No changes.
View
1  tests/regressiontests/admin_scripts/lib3/_addsitedir.py
@@ -0,0 +1 @@
+import os.path, site; site.addsitedir(os.path.dirname(__file__))
View
1  tests/regressiontests/admin_scripts/lib3/egg_module.pth
@@ -0,0 +1 @@
+test_egg.egg
View
1  tests/regressiontests/admin_scripts/lib3/exapps-nspkg.pth
@@ -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)
View
0  tests/regressiontests/admin_scripts/lib3/exapps/app3/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/lib3/exapps/app3/management/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/__init__.py
No changes.
View
9 tests/regressiontests/admin_scripts/lib3/exapps/app3/management/commands/app3_command1.py
@@ -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'
View
0  tests/regressiontests/admin_scripts/lib3/exapps/app3/models.py
No changes.
View
BIN  tests/regressiontests/admin_scripts/lib3/test_egg.egg
Binary file not shown
View
100 tests/regressiontests/admin_scripts/tests.py
@@ -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)
+
+
View
BIN  tests/regressiontests/i18n/eggs/localeegg.egg
Binary file not shown
View
28 tests/regressiontests/i18n/tests.py
@@ -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):
View
6 tests/regressiontests/staticfiles_tests/tests.py
@@ -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)
View
6 tests/regressiontests/templates/loaders.py
@@ -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]
View
16 tests/regressiontests/templates/tests.py
@@ -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.