Permalink
Browse files

Use python import hooks instead of Django magic

  • Loading branch information...
1 parent 135fcc1 commit 46727dadf8ca96377f2e96cd820abfd5734d00b8 @dcramer committed Sep 13, 2012
Showing with 85 additions and 32 deletions.
  1. +80 −0 logan/importer.py
  2. +4 −9 logan/runner.py
  3. +0 −22 logan/settings.py
  4. +1 −1 setup.py
View
@@ -0,0 +1,80 @@
+"""
+logan.importer
+~~~~~~~~~~~~~~
+
+:copyright: (c) 2012 David Cramer.
+:license: Apache License 2.0, see LICENSE for more details.
+"""
+
+import imp
+import sys
+from django.core.exceptions import ImproperlyConfigured
+from django.utils.importlib import import_module
+from logan.settings import load_settings, create_module
+
+installed = False
+
+
+def install(name, config_path, default_settings, **kwargs):
+ global installed
+
+ if installed:
+ # TODO: reinstall
+ return
+
+ sys.meta_path.append(LoganImporter(name, config_path, default_settings, **kwargs))
+ installed = True
+
+
+class LoganImporter(object):
+ def __init__(self, name, config_path, default_settings=None, allow_extras=True):
+ self.name = name
+ self.config_path = config_path
+ self.default_settings = default_settings
+ self.allow_extras = allow_extras
+ self.validate()
+
+ def __repr__(self):
+ return "<%s for '%s' (%s)>" % (type(self), self.name, self.config_path)
+
+ def validate(self):
+ # if self.name is None:
+ # raise ImproperlyConfigured(self.error_msg % self.class_varname)
+ pass
+
+ def find_module(self, fullname, path=None):
+ if fullname != self.name:
+ return
+
+ return LoganLoader(self.name, self.config_path, self.default_settings)
+
+
+class LoganLoader(object):
+ def __init__(self, name, config_path, default_settings=None, allow_extras=True):
+ self.name = name
+ self.config_path = config_path
+ self.default_settings = default_settings
+ self.allow_extras = allow_extras
+
+ def load_module(self, fullname):
+ # TODO: is this needed?
+ if fullname in sys.modules:
+ return sys.modules[fullname] # pragma: no cover
+
+ if self.default_settings:
+ default_settings_mod = import_module(self.default_settings)
+ else:
+ default_settings_mod = None
+
+ settings_mod = create_module(self.name)
+
+ # Django doesn't play too nice without the config file living as a real file, so let's fake it.
+ settings_mod.__file__ = self.config_path
+
+ # install the default settings for this app
+ load_settings(default_settings_mod, allow_extras=self.allow_extras, settings=settings_mod)
+
+ # install the custom settings for this app
+ load_settings(self.config_path, allow_extras=self.allow_extras, settings=settings_mod)
+
+ return settings_mod
View
@@ -9,13 +9,13 @@
from __future__ import absolute_import
from django.core import management
-from django.utils.importlib import import_module
from optparse import OptionParser
import os
import re
import sys
-from logan.settings import create_default_settings, install_settings
+from logan import importer
+from logan.settings import create_default_settings
def sanitize_name(project):
@@ -119,14 +119,9 @@ def run_app(project=None, default_config_path=None, default_settings=None,
if not os.path.exists(config_path):
raise ValueError("Configuration file does not exist. Use '%s init' to initialize the file." % runner_name)
- if default_settings:
- default_settings_mod = import_module(default_settings)
- # TODO: logan should create a proxy module for its settings
- # management.setup_environ(settings_mod, default_settings)
- else:
- default_settings_mod = None
+ os.environ['DJANGO_SETTINGS_MODULE'] = 'logan_config'
- install_settings(config_path, default_settings_mod, allow_extras=allow_extras)
+ importer.install('logan_config', config_path, default_settings, allow_extras=allow_extras)
if initializer is not None:
from django.conf import settings
View
@@ -41,28 +41,6 @@ def create_module(name, install=True):
return mod
-def install_settings(filename, default_settings=global_settings, silent=False, allow_extras=True, settings=_settings):
- settings_mod = create_module('logan_config')
-
- # Django doesn't play too nice without the config file living as a real file, so let's fake it.
- settings_mod.__file__ = filename
-
- # Gunicorn doesn't play nice without DJANGO_SETTINGS_MODULE
- os.environ['DJANGO_SETTINGS_MODULE'] = filename
-
- # install the default settings for this app
- load_settings(default_settings, allow_extras=allow_extras, settings=settings_mod)
-
- # install the custom settings for this app
- load_settings(filename, allow_extras=allow_extras, settings=settings_mod)
-
- # HACK: we need to ensure that the settings object doesnt configure itself until we tell it to
- settings_inst = Settings('logan_config')
- settings._wrapped = settings_inst
-
- return settings
-
-
def load_settings(mod_or_filename, silent=False, allow_extras=True, settings=_settings):
if isinstance(mod_or_filename, basestring):
conf = create_module('temp_config', install=False)
View
@@ -14,7 +14,7 @@
setup(
name='logan',
- version='0.4.0',
+ version='0.5.0',
author='David Cramer',
author_email='dcramer@gmail.com',
url='http://github.com/dcramer/logan',

0 comments on commit 46727da

Please sign in to comment.