diff --git a/django_pyvows/context.py b/django_pyvows/context.py index 3248a38..3519ca2 100644 --- a/django_pyvows/context.py +++ b/django_pyvows/context.py @@ -17,6 +17,7 @@ from django.http import HttpRequest from django_pyvows import http_helpers from django_pyvows.assertions import Url, Model, Template from django_pyvows.server import DjangoServer +from django_pyvows.settings_manager import settings_tracker DEFAULT_PORT = 3331 DEFAULT_HOST = '127.0.0.1' @@ -28,6 +29,7 @@ class DjangoContext(Vows.Context): if not settings_path: raise RuntimeError('The settings_path argument is required.') os.environ['DJANGO_SETTINGS_MODULE'] = settings_path + settings_tracker.install() def __init__(self, parent): super(DjangoContext, self).__init__(parent) @@ -78,7 +80,7 @@ class DjangoHTTPContext(DjangoContext): self.address = (host, port) self.server = DjangoServer(host, port) - self.server.start() + self.server.start(self.settings) def __init__(self, parent): super(DjangoHTTPContext, self).__init__(parent) diff --git a/django_pyvows/server.py b/django_pyvows/server.py index cb1cc36..5d793d9 100644 --- a/django_pyvows/server.py +++ b/django_pyvows/server.py @@ -11,7 +11,7 @@ import sys import urllib2 -from threading import Thread +from threading import Thread, local, current_thread from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler from pyvows import Vows @@ -137,9 +137,14 @@ class DjangoServer(HTTPServer, object): HTTPServer.__init__(self, (host, int(port)), WSGIRequestHandler) self.app = WSGIHandler() - def start(self): + def start(self, settings): self.server_activate() def make_response(): + thread = current_thread() + if not hasattr(thread, "settings"): + thread.settings = local() + for key, value in settings.items(): + setattr(thread.settings, key, value) while True: self.handle_request() self.thr = Thread(target=make_response) diff --git a/django_pyvows/settings_manager.py b/django_pyvows/settings_manager.py index 331a649..5633a6a 100644 --- a/django_pyvows/settings_manager.py +++ b/django_pyvows/settings_manager.py @@ -9,25 +9,34 @@ # Copyright (c) 2011 Rafael Caricio rafael@caricio.com import sys +from threading import current_thread -class ModulesTracker(object): +class SettingsTracker(object): def install(self): - self.previous_modules = sys.modules.copy() - self.real_import = __builtins__['__import__'] - __builtins__['__import__'] = self._import - self.new_modules = {} + actual_import = __builtins__['__import__'] + if actual_import != self._import: + self.real_import = actual_import + __builtins__['__import__'] = self._import def _import(self, name, globals=None, locals=None, fromlist=[], level=-1): result = apply(self.real_import, (name, globals, locals, fromlist, level)) - self.new_modules[name] = 1 + if name == 'django.conf': + result.settings = VowsSettings(result.settings) + elif name == "django" and 'conf' in (fromlist or []): + result.conf.settings = VowsSettings(result.settings) return result - def reload(self): - for modname in self.new_modules.keys(): - if not self.previous_modules.has_key(modname): - del(sys.modules[modname]) +class VowsSettings(object): - def uninstall(self): - __builtins__['__import__'] = self.real_import + def __init__(self, original_settings): + self.original_settings = original_settings + def __getattr__(self, attr_name): + thread = current_thread() + if hasattr(thread, "settings"): + if hasattr(thread.settings, attr_name): + return getattr(thread.settings, attr_name) + return getattr(self.original_settings, attr_name) + +settings_tracker = SettingsTracker() diff --git a/vows/settings_vows.py b/vows/settings_vows.py index 929cebc..fee4011 100644 --- a/vows/settings_vows.py +++ b/vows/settings_vows.py @@ -11,44 +11,33 @@ from pyvows import Vows, expect from django_pyvows.context import DjangoContext, DjangoHTTPContext -from django_pyvows.settings_manager import ModulesTracker +#from django_pyvows.settings_manager import settings_tracker @Vows.batch class SettingsVows(DjangoContext): - class WhenIUseTheModulesTracker(DjangoContext): + #class WhenIUseTheModulesTracker(DjangoContext): - def topic(self): - modules_tracker = ModulesTracker() - modules_tracker.install() - import to_test - return modules_tracker + #def topic(self): + #settings_tracker.install() + #import to_test + #return modules_tracker - def should_track_the_new_imported_module(self, topic): - expect('to_test' in topic.new_modules).to_be_true() + #def should_track_the_new_imported_module(self, topic): + #expect('to_test' in topic.new_modules).to_be_true() - class WhenIReloadTheImportedModule(DjangoContext): + #class WhenIReloadTheImportedModule(DjangoContext): - def topic(self, modules_tracker): - import to_test - imported_first_time_at = to_test.imported_at - modules_tracker.reload() - import to_test - return (modules_tracker, imported_first_time_at, to_test.imported_at) + #def topic(self, modules_tracker): + #import to_test + #imported_first_time_at = to_test.imported_at + #modules_tracker.reload() + #import to_test + #return (modules_tracker, imported_first_time_at, to_test.imported_at) - def should_be_different_instances(self, topic): - expect(topic[1]).not_to_equal(topic[2]) - - class WhenIUninstall(DjangoContext): - - def topic(self, last_topic): - modules_tracker = last_topic[0] - modules_tracker.uninstall() - return __builtins__['__import__'] - - def should_be_restored_to_original_import_function(self, topic): - expect(topic.__module__).to_equal('__builtin__') + #def should_be_different_instances(self, topic): + #expect(topic[1]).not_to_equal(topic[2]) class CannotSayHelloWithoutName(DjangoHTTPContext):