Esempio n. 1
0
    def fixture_dirs(self):
        """
        Return a list of fixture directories.

        The list contains the 'fixtures' subdirectory of each installed
        application, if it exists, the directories in FIXTURE_DIRS, and the
        current directory.
        """
        dirs = []
        fixture_dirs = settings.FIXTURE_DIRS
        if len(fixture_dirs) != len(set(fixture_dirs)):
            raise ImproperlyConfigured(
                "settings.FIXTURE_DIRS contains duplicates.")
        for app_config in apps.get_app_configs():
            app_label = app_config.label
            app_dir = os.path.join(app_config.path, 'fixtures')
            if app_dir in fixture_dirs:
                raise ImproperlyConfigured(
                    "'%s' is a default fixture directory for the '%s' app "
                    "and cannot be listed in settings.FIXTURE_DIRS." %
                    (app_dir, app_label))

            if self.app_label and app_label != self.app_label:
                continue
            if os.path.isdir(app_dir):
                dirs.append(app_dir)
        dirs.extend(list(fixture_dirs))
        dirs.append('')
        dirs = [upath(os.path.abspath(os.path.realpath(d))) for d in dirs]
        return dirs
Esempio n. 2
0
 def _path_from_module(self, module):
     """Attempt to determine app's filesystem path from its module."""
     # See #21874 for extended discussion of the behavior of this method in
     # various cases.
     # Convert paths to list because Python 3's _NamespacePath does not
     # support indexing.
     paths = list(getattr(module, '__path__', []))
     if len(paths) != 1:
         filename = getattr(module, '__file__', None)
         if filename is not None:
             paths = [os.path.dirname(filename)]
         else:
             # For unknown reasons, sometimes the list returned by __path__
             # contains duplicates that must be removed (#25246).
             paths = list(set(paths))
     if len(paths) > 1:
         raise ImproperlyConfigured(
             "The app module %r has multiple filesystem locations (%r); "
             "you must configure this app with an AppConfig subclass "
             "with a 'path' class attribute." % (module, paths))
     elif not paths:
         raise ImproperlyConfigured(
             "The app module %r has no filesystem location, "
             "you must configure this app with an AppConfig subclass "
             "with a 'path' class attribute." % (module, ))
     return upath(paths[0])
Esempio n. 3
0
 def get_connection_params(self):
     settings_dict = self.settings_dict
     if not settings_dict['NAME']:
         from arouse._dj.core.exceptions import ImproperlyConfigured
         raise ImproperlyConfigured(
             "settings.DATABASES is improperly configured. "
             "Please supply the NAME value.")
     kwargs = {
         'database': settings_dict['NAME'],
         'detect_types': Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES,
     }
     kwargs.update(settings_dict['OPTIONS'])
     # Always allow the underlying SQLite connection to be shareable
     # between multiple threads. The safe-guarding will be handled at a
     # higher level by the `BaseDatabaseWrapper.allow_thread_sharing`
     # property. This is necessary as the shareability is disabled by
     # default in pysqlite and it cannot be changed once a connection is
     # opened.
     if 'check_same_thread' in kwargs and kwargs['check_same_thread']:
         warnings.warn(
             'The `check_same_thread` option was provided and set to '
             'True. It will be overridden with False. Use the '
             '`DatabaseWrapper.allow_thread_sharing` property instead '
             'for controlling thread shareability.', RuntimeWarning)
     kwargs.update({'check_same_thread': False})
     if self.features.can_share_in_memory_db:
         kwargs.update({'uri': True})
     return kwargs
Esempio n. 4
0
    def __init__(self, settings_module):
        # update this dict from global settings (but only for ALL_CAPS settings)
        for setting in dir(global_settings):
            if setting.isupper():
                setattr(self, setting, getattr(global_settings, setting))

        # store the settings module in case someone later cares
        self.SETTINGS_MODULE = settings_module

        mod = importlib.import_module(self.SETTINGS_MODULE)

        tuple_settings = (
            "INSTALLED_APPS",
            "TEMPLATE_DIRS",
            "LOCALE_PATHS",
        )
        self._explicit_settings = set()
        for setting in dir(mod):
            if setting.isupper():
                setting_value = getattr(mod, setting)

                if (setting in tuple_settings and
                        not isinstance(setting_value, (list, tuple))):
                    raise ImproperlyConfigured("The %s setting must be a list or a tuple. " % setting)
                setattr(self, setting, setting_value)
                self._explicit_settings.add(setting)

        if not self.SECRET_KEY:
            raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")

        if hasattr(time, 'tzset') and self.TIME_ZONE:
            # When we can, attempt to validate the timezone. If we can't find
            # this file, no check happens and it's harmless.
            zoneinfo_root = '/usr/share/zoneinfo'
            if (os.path.exists(zoneinfo_root) and not
                    os.path.exists(os.path.join(zoneinfo_root, *(self.TIME_ZONE.split('/'))))):
                raise ValueError("Incorrect timezone setting: %s" % self.TIME_ZONE)
            # Move the time zone info into os.environ. See ticket #2315 for why
            # we don't do this unconditionally (breaks Windows).
            os.environ['TZ'] = self.TIME_ZONE
            time.tzset()
Esempio n. 5
0
 def _get_test_db_name(self):
     test_database_name = self.connection.settings_dict['TEST']['NAME']
     can_share_in_memory_db = self.connection.features.can_share_in_memory_db
     if test_database_name and test_database_name != ':memory:':
         if 'mode=memory' in test_database_name and not can_share_in_memory_db:
             raise ImproperlyConfigured(
                 "Using a shared memory database with `mode=memory` in the "
                 "database name is not supported in your environment, "
                 "use `:memory:` instead.")
         return test_database_name
     if can_share_in_memory_db:
         return 'file:memorydb_%s?mode=memory&cache=shared' % self.connection.alias
     return ':memory:'
Esempio n. 6
0
def _setup_environment(environ):
    # Cygwin requires some special voodoo to set the environment variables
    # properly so that Oracle will see them.
    if platform.system().upper().startswith('CYGWIN'):
        try:
            import ctypes
        except ImportError as e:
            from arouse._dj.core.exceptions import ImproperlyConfigured
            raise ImproperlyConfigured("Error loading ctypes: %s; "
                                       "the Oracle backend requires ctypes to "
                                       "operate correctly under Cygwin." % e)
        kernel32 = ctypes.CDLL('kernel32')
        for name, value in environ:
            kernel32.SetEnvironmentVariableA(name, value)
    else:
        os.environ.update(environ)
Esempio n. 7
0
    def _setup(self, name=None):
        """
        Load the settings module pointed to by the environment variable. This
        is used the first time we need any settings at all, if the user has not
        previously configured the settings manually.
        """
        settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
        if not settings_module:
            desc = ("setting %s" % name) if name else "settings"
            raise ImproperlyConfigured(
                "Requested %s, but settings are not configured. "
                "You must either define the environment variable %s "
                "or call settings.configure() before accessing settings."
                % (desc, ENVIRONMENT_VARIABLE))

        self._wrapped = Settings(settings_module)
Esempio n. 8
0
    def databases(self):
        if self._databases is None:
            self._databases = settings.DATABASES
        if self._databases == {}:
            self._databases = {
                DEFAULT_DB_ALIAS: {
                    'ENGINE': 'arouse._dj.db.backends.dummy',
                },
            }
        if self._databases[DEFAULT_DB_ALIAS] == {}:
            self._databases[DEFAULT_DB_ALIAS][
                'ENGINE'] = 'arouse._dj.db.backends.dummy'

        if DEFAULT_DB_ALIAS not in self._databases:
            raise ImproperlyConfigured("You must define a '%s' database" %
                                       DEFAULT_DB_ALIAS)
        return self._databases
Esempio n. 9
0
    def prepare_sql_script(self, sql):
        """
        Takes an SQL script that may contain multiple lines and returns a list
        of statements to feed to successive cursor.execute() calls.

        Since few databases are able to process raw SQL scripts in a single
        cursor.execute() call and PEP 249 doesn't talk about this use case,
        the default implementation is conservative.
        """
        try:
            import sqlparse
        except ImportError:
            raise ImproperlyConfigured(
                "sqlparse is required if you don't split your SQL "
                "statements manually.")
        else:
            return [
                sqlparse.format(statement, strip_comments=True)
                for statement in sqlparse.split(sql) if statement
            ]
Esempio n. 10
0
 def get_connection_params(self):
     settings_dict = self.settings_dict
     # None may be used to connect to the default 'postgres' db
     if settings_dict['NAME'] == '':
         raise ImproperlyConfigured(
             "settings.DATABASES is improperly configured. "
             "Please supply the NAME value.")
     conn_params = {
         'database': settings_dict['NAME'] or 'postgres',
     }
     conn_params.update(settings_dict['OPTIONS'])
     conn_params.pop('isolation_level', None)
     if settings_dict['USER']:
         conn_params['user'] = settings_dict['USER']
     if settings_dict['PASSWORD']:
         conn_params['password'] = force_str(settings_dict['PASSWORD'])
     if settings_dict['HOST']:
         conn_params['host'] = settings_dict['HOST']
     if settings_dict['PORT']:
         conn_params['port'] = settings_dict['PORT']
     return conn_params
Esempio n. 11
0
def load_backend(backend_name):
    """
    Return a database backend's "base" module given a fully qualified database
    backend name, or raise an error if it doesn't exist.
    """
    # This backend was renamed in Django 1.9.
    if backend_name == 'arouse._dj.db.backends.postgresql_psycopg2':
        backend_name = 'arouse._dj.db.backends.postgresql'

    try:
        return import_module('%s.base' % 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(upath(__file__)),
                                   'backends')
        try:
            builtin_backends = [
                name for _, name, ispkg in pkgutil.iter_modules(
                    [npath(backend_dir)]) if ispkg
                and name not in {'base', 'dummy', 'postgresql_psycopg2'}
            ]
        except EnvironmentError:
            builtin_backends = []
        if backend_name not in [
                'arouse._dj.db.backends.%s' % b for b in builtin_backends
        ]:
            backend_reprs = map(repr, sorted(builtin_backends))
            error_msg = ("%r isn't an available database backend.\n"
                         "Try using 'arouse._dj.db.backends.XXX', where XXX "
                         "is one of:\n    %s\nError was: %s" %
                         (backend_name, ", ".join(backend_reprs), e_user))
            raise ImproperlyConfigured(error_msg)
        else:
            # If there's some other error, this must be an error in Django
            raise
Esempio n. 12
0
def complain(*args, **kwargs):
    raise ImproperlyConfigured("settings.DATABASES is improperly configured. "
                               "Please supply the ENGINE value. Check "
                               "settings documentation for more details.")
Esempio n. 13
0
from arouse._dj.utils.safestring import SafeBytes

try:
    import pytz
except ImportError:
    pytz = None

try:
    try:
        from pysqlite2 import dbapi2 as Database
    except ImportError:
        from sqlite3 import dbapi2 as Database
except ImportError as exc:
    from arouse._dj.core.exceptions import ImproperlyConfigured
    raise ImproperlyConfigured(
        "Error loading either pysqlite2 or sqlite3 modules (tried in that order): %s"
        % exc)

# Some of these import sqlite3, so import them after checking if it's installed.
from .client import DatabaseClient  # isort:skip
from .creation import DatabaseCreation  # isort:skip
from .features import DatabaseFeatures  # isort:skip
from .introspection import DatabaseIntrospection  # isort:skip
from .operations import DatabaseOperations  # isort:skip
from .schema import DatabaseSchemaEditor  # isort:skip

DatabaseError = Database.DatabaseError
IntegrityError = Database.IntegrityError


def adapt_datetime_warn_on_aware_datetime(value):
Esempio n. 14
0
 def __setattr__(self, name, value):
     if name in ("MEDIA_URL", "STATIC_URL") and value and not value.endswith('/'):
         raise ImproperlyConfigured("If set, %s must end with a slash" % name)
     object.__setattr__(self, name, value)
Esempio n. 15
0
from arouse._dj.conf import settings
from arouse._dj.db import utils
from arouse._dj.db.backends import utils as backend_utils
from arouse._dj.db.backends.base.base import BaseDatabaseWrapper
from arouse._dj.utils import six, timezone
from arouse._dj.utils.deprecation import RemovedInDjango20Warning
from arouse._dj.utils.encoding import force_str
from arouse._dj.utils.functional import cached_property
from arouse._dj.utils.safestring import SafeBytes, SafeText

try:
    import MySQLdb as Database
except ImportError as e:
    from arouse._dj.core.exceptions import ImproperlyConfigured
    raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)

from MySQLdb.constants import CLIENT, FIELD_TYPE                # isort:skip
from MySQLdb.converters import Thing2Literal, conversions       # isort:skip

# Some of these import MySQLdb, so import them after checking if it's installed.
from .client import DatabaseClient                          # isort:skip
from .creation import DatabaseCreation                      # isort:skip
from .features import DatabaseFeatures                      # isort:skip
from .introspection import DatabaseIntrospection            # isort:skip
from .operations import DatabaseOperations                  # isort:skip
from .schema import DatabaseSchemaEditor                    # isort:skip
from .validation import DatabaseValidation                  # isort:skip

# We want version (1, 2, 1, 'final', 2) or later. We can't just use
# lexicographic ordering in this check because then (1, 2, 1, 'gamma')
Esempio n. 16
0
    def populate(self, installed_apps=None):
        """
        Loads application configurations and models.

        This method imports each application module and then each model module.

        It is thread safe and idempotent, but not reentrant.
        """
        if self.ready:
            return

        # populate() might be called by two threads in parallel on servers
        # that create threads before initializing the WSGI callable.
        with self._lock:
            if self.ready:
                return

            # app_config should be pristine, otherwise the code below won't
            # guarantee that the order matches the order in INSTALLED_APPS.
            if self.app_configs:
                raise RuntimeError("populate() isn't reentrant")

            # Load app configs and app modules.
            for entry in installed_apps:
                if isinstance(entry, AppConfig):
                    app_config = entry
                else:
                    app_config = AppConfig.create(entry)
                if app_config.label in self.app_configs:
                    raise ImproperlyConfigured(
                        "Application labels aren't unique, "
                        "duplicates: %s" % app_config.label)

                self.app_configs[app_config.label] = app_config

            # Check for duplicate app names.
            counts = Counter(app_config.name
                             for app_config in self.app_configs.values())
            duplicates = [
                name for name, count in counts.most_common() if count > 1
            ]
            if duplicates:
                raise ImproperlyConfigured("Application names aren't unique, "
                                           "duplicates: %s" %
                                           ", ".join(duplicates))

            self.apps_ready = True

            # Load models.
            for app_config in self.app_configs.values():
                all_models = self.all_models[app_config.label]
                app_config.import_models(all_models)

            self.clear_cache()

            self.models_ready = True

            for app_config in self.get_app_configs():
                app_config.ready()

            self.ready = True
Esempio n. 17
0
from arouse._dj.conf import settings
from arouse._dj.core.exceptions import ImproperlyConfigured
from arouse._dj.db import DEFAULT_DB_ALIAS
from arouse._dj.db.backends.base.base import BaseDatabaseWrapper
from arouse._dj.db.backends.base.validation import BaseDatabaseValidation
from arouse._dj.db.utils import DatabaseError as WrappedDatabaseError
from arouse._dj.utils.encoding import force_str
from arouse._dj.utils.functional import cached_property
from arouse._dj.utils.safestring import SafeBytes, SafeText

try:
    import psycopg2 as Database
    import psycopg2.extensions
    import psycopg2.extras
except ImportError as e:
    raise ImproperlyConfigured("Error loading psycopg2 module: %s" % e)


def psycopg2_version():
    version = psycopg2.__version__.split(' ', 1)[0]
    return tuple(int(v) for v in version.split('.') if v.isdigit())


PSYCOPG2_VERSION = psycopg2_version()

if PSYCOPG2_VERSION < (2, 4, 5):
    raise ImproperlyConfigured(
        "psycopg2_version 2.4.5 or newer is required; you have %s" %
        psycopg2.__version__)

# Some of these import psycopg2, so import them after checking if it's installed.
Esempio n. 18
0
    def create(cls, entry):
        """
        Factory that creates an app config from an entry in INSTALLED_APPS.
        """
        try:
            # If import_module succeeds, entry is a path to an app module,
            # which may specify an app config class with default_app_config.
            # Otherwise, entry is a path to an app config class or an error.
            module = import_module(entry)

        except ImportError:
            # Track that importing as an app module failed. If importing as an
            # app config class fails too, we'll trigger the ImportError again.
            module = None

            mod_path, _, cls_name = entry.rpartition('.')

            # Raise the original exception when entry cannot be a path to an
            # app config class.
            if not mod_path:
                raise

        else:
            try:
                # If this works, the app module specifies an app config class.
                entry = module.default_app_config
            except AttributeError:
                # Otherwise, it simply uses the default app config class.
                return cls(entry, module)
            else:
                mod_path, _, cls_name = entry.rpartition('.')

        # If we're reaching this point, we must attempt to load the app config
        # class located at <mod_path>.<cls_name>
        mod = import_module(mod_path)
        try:
            cls = getattr(mod, cls_name)
        except AttributeError:
            if module is None:
                # If importing as an app module failed, that error probably
                # contains the most informative traceback. Trigger it again.
                import_module(entry)
            else:
                raise

        # Check for obvious errors. (This check prevents duck typing, but
        # it could be removed if it became a problem in practice.)
        if not issubclass(cls, AppConfig):
            raise ImproperlyConfigured("'%s' isn't a subclass of AppConfig." %
                                       entry)

        # Obtain app name here rather than in AppClass.__init__ to keep
        # all error checking for entries in INSTALLED_APPS in one place.
        try:
            app_name = cls.name
        except AttributeError:
            raise ImproperlyConfigured("'%s' must supply a name attribute." %
                                       entry)

        # Ensure app_name points to a valid module.
        app_module = import_module(app_name)

        # Entry is a path to an app config class.
        return cls(app_name, app_module)
Esempio n. 19
0
 def _require_pytz(self):
     if settings.USE_TZ and pytz is None:
         raise ImproperlyConfigured("This query requires pytz, but it isn't installed.")
Esempio n. 20
0
        os.environ.update(environ)

_setup_environment([
    # Oracle takes client-side character set encoding from the environment.
    ('NLS_LANG', '.UTF8'),
    # This prevents unicode from getting mangled by getting encoded into the
    # potentially non-unicode database character set.
    ('ORA_NCHAR_LITERAL_REPLACE', 'TRUE'),
])


try:
    import cx_Oracle as Database
except ImportError as e:
    from arouse._dj.core.exceptions import ImproperlyConfigured
    raise ImproperlyConfigured("Error loading cx_Oracle module: %s" % e)

# Some of these import cx_Oracle, so import them after checking if it's installed.
from .client import DatabaseClient                          # NOQA isort:skip
from .creation import DatabaseCreation                      # NOQA isort:skip
from .features import DatabaseFeatures                      # NOQA isort:skip
from .introspection import DatabaseIntrospection            # NOQA isort:skip
from .operations import DatabaseOperations                  # NOQA isort:skip
from .schema import DatabaseSchemaEditor                    # NOQA isort:skip
from .utils import Oracle_datetime, convert_unicode         # NOQA isort:skip

DatabaseError = Database.DatabaseError
IntegrityError = Database.IntegrityError


class _UninitializedOperatorsDescriptor(object):