From a2f82e7ea493a515a245dbaf3de425fe9e520248 Mon Sep 17 00:00:00 2001 From: Pavel Zinovkin Date: Thu, 5 Apr 2012 19:57:41 +0400 Subject: [PATCH] Fixed issue with threading --- README.rst | 2 +- example/example/settings.py | 2 +- fabfile.py | 6 +++ fest/template.py | 74 +++++++++++++++++++++++++++++++------ requirements.txt | 4 +- setup.py | 2 +- 6 files changed, 73 insertions(+), 17 deletions(-) create mode 100644 fabfile.py diff --git a/README.rst b/README.rst index 43de11b..ac3e1cc 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ Installation :: - export V8_SVN_URL="http://v8.googlecode.com/svn/trunk/@10412" + export V8_SVN_URL="http://v8.googlecode.com/svn/trunk/@10875" pip install -r requirements.txt diff --git a/example/example/settings.py b/example/example/settings.py index d94b15c..28ea19e 100644 --- a/example/example/settings.py +++ b/example/example/settings.py @@ -3,7 +3,7 @@ PROJECT_ROOT = os.path.dirname(__file__) -DEBUG = False +DEBUG = True TEMPLATE_DEBUG = DEBUG ADMINS = ( diff --git a/fabfile.py b/fabfile.py new file mode 100644 index 0000000..f7b7b2f --- /dev/null +++ b/fabfile.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from fabric.api import local + + +def test(): + local('django-admin.py test --settings=fest.tests.settings') diff --git a/fest/template.py b/fest/template.py index 33769a7..2463ef4 100644 --- a/fest/template.py +++ b/fest/template.py @@ -18,6 +18,55 @@ def fest_error(message): raise TemplateSyntaxError(message) +class JSLocker(PyV8.JSLocker): + + def __enter__(self): + self.enter() + + if JSContext.entered: + self.leave() + raise RuntimeError('Lock should be acquired before enter' + ' the context') + + return self + + def __exit__(self, exc_type, exc_value, traceback): + if JSContext.entered: + self.leave() + raise RuntimeError('Lock should be released after leave' + ' the context') + + self.leave() + + def __nonzero__(self): + return self.entered() + + +class JSContext(PyV8.JSContext): + + def __init__(self, obj=None, extensions=None, ctxt=None): + if JSLocker.active: + self.lock = JSLocker() + self.lock.enter() + + if ctxt: + PyV8.JSContext.__init__(self, ctxt) + else: + PyV8.JSContext.__init__(self, obj, extensions or []) + + def __enter__(self): + self.enter() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.leave() + if hasattr(JSLocker, 'lock'): + self.lock.leave() + self.lock = None + + del self + + class TemplateGlobal(PyV8.JSClass): def __init__(self, template): @@ -63,7 +112,7 @@ def __init__(self, template_string, origin=None, @property def context(self): if not hasattr(self, '_context'): - self._context = PyV8.JSContext(TemplateGlobal(self)) + self._context = JSContext(TemplateGlobal(self)) return self._context def compile(self): @@ -74,16 +123,17 @@ def compile(self): def render(self, context): - with self.context as env: - if not settings.DEBUG: - template = self.template_string - else: - template = self.compile() + with JSLocker(): + with self.context as env: + if not settings.DEBUG: + template = self.template_string + else: + template = self.compile() - # maybe i'm just stupid - template = """(function(json_string, fest_error) { - return %s(JSON.parse(json_string), fest_error); - })""" % template + # maybe i'm just stupid + template = """(function(json_string, fest_error) { + return %s(JSON.parse(json_string), fest_error); + })""" % template - func = env.eval(template) - return func(json.dumps(list(context).pop()), fest_error) + func = env.eval(template) + return func(json.dumps(list(context).pop()), fest_error) diff --git a/requirements.txt b/requirements.txt index 6e5cc44..f882e08 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -git+git://github.com/django/django.git@996f702#egg=django +Django==1.4 -svn+http://pyv8.googlecode.com/svn/trunk/@429#egg=PyV8 +svn+http://pyv8.googlecode.com/svn/trunk/@433#egg=PyV8 diff --git a/setup.py b/setup.py index d29b9fd..266179c 100644 --- a/setup.py +++ b/setup.py @@ -11,6 +11,6 @@ 'PyV8==1.0', ], dependency_links=[ - 'svn+http://pyv8.googlecode.com/svn/trunk/@429#egg=PyV8-1.0', + 'svn+http://pyv8.googlecode.com/svn/trunk/@433#egg=PyV8-1.0', ] )