diff options
| author | Chris McDonough <chrism@agendaless.com> | 2008-09-04 05:58:05 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2008-09-04 05:58:05 +0000 |
| commit | 23756f9943958e957270ad84912dc074ddc3b026 (patch) | |
| tree | 936a47d40f5f5df1c1b9d89bc2c627e27148ccda | |
| parent | 6f97fecf3b0a4fa9f3cb193b6efad3fc6fd67d44 (diff) | |
| download | pyramid-23756f9943958e957270ad84912dc074ddc3b026.tar.gz pyramid-23756f9943958e957270ad84912dc074ddc3b026.tar.bz2 pyramid-23756f9943958e957270ad84912dc074ddc3b026.zip | |
- Allow configuration cache to be bypassed by actions which include
special "uncacheable" discriminators (for actions that have
variable results).
| -rw-r--r-- | CHANGES.txt | 4 | ||||
| -rw-r--r-- | repoze/bfg/registry.py | 13 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_registry.py | 19 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_zcml.py | 53 | ||||
| -rw-r--r-- | repoze/bfg/zcml.py | 28 |
5 files changed, 94 insertions, 23 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index c4ae68324..332b2b3b3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,6 +4,10 @@ Next Release - Add startup process docs. + - Allow configuration cache to be bypassed by actions which include + special "uncacheable" discriminators (for actions that have + variable results). + Bug Fixes - Move core repoze.bfg ZCML into a ``repoze.bfg.includes`` package so we can diff --git a/repoze/bfg/registry.py b/repoze/bfg/registry.py index 7d27a7126..6afd8de6c 100644 --- a/repoze/bfg/registry.py +++ b/repoze/bfg/registry.py @@ -50,13 +50,13 @@ def makeRegistry(filename, package, options=None, lock=threading.Lock()): try: registry = Components(package.__name__) registry_manager.set(registry) - original_getSiteManager.sethook(getSiteManager) - zope.component.getGlobalSiteManager = registry_manager.get - zcml_configure(filename, package=package) if options is None: options = {} settings = Settings(options) registry.registerUtility(settings, ISettings) + original_getSiteManager.sethook(getSiteManager) + zope.component.getGlobalSiteManager = registry_manager.get + zcml_configure(filename, package=package) return registry finally: zope.component.getGlobalSiteManager = getGlobalSiteManager @@ -66,7 +66,7 @@ def makeRegistry(filename, package, options=None, lock=threading.Lock()): class Settings(object): implements(ISettings) def __init__(self, options): - self.reload_templates = options.get('reload_templates', False) + self.__dict__.update(options) def getSiteManager(context=None): if context is None: @@ -82,8 +82,9 @@ def asbool(s): return s.lower() in ('t', 'true', 'y', 'yes', 'on', '1') def get_options(kw): - reload_templates = asbool(kw.get('reload_templates')) - return {'reload_templates':reload_templates} + return { + 'reload_templates':asbool(kw.get('reload_templates')), + } from zope.testing.cleanup import addCleanUp try: diff --git a/repoze/bfg/tests/test_registry.py b/repoze/bfg/tests/test_registry.py index de8481fd8..efc99b41a 100644 --- a/repoze/bfg/tests/test_registry.py +++ b/repoze/bfg/tests/test_registry.py @@ -42,17 +42,16 @@ class TestGetOptions(unittest.TestCase): from repoze.bfg.registry import get_options return get_options - def test_it(self): + def test_reload_templates(self): get_options = self._getFUT() - self.assertEqual(get_options({}), - {'reload_templates':False}) - self.assertEqual(get_options({'reload_templates':'false'}), - {'reload_templates':False}) - self.assertEqual(get_options({'reload_templates':'t'}), - {'reload_templates':True}) - self.assertEqual(get_options({'reload_templates':'1'}), - {'reload_templates':True}) - + result = get_options({}) + self.assertEqual(result['reload_templates'], False) + result = get_options({'reload_templates':'false'}) + self.assertEqual(result['reload_templates'], False) + result = get_options({'reload_templates':'t'}) + self.assertEqual(result['reload_templates'], True) + result = get_options({'reload_templates':'1'}) + self.assertEqual(result['reload_templates'], True) class TestThreadLocalRegistryManager(unittest.TestCase, PlacelessSetup): def setUp(self): diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py index 28ea04ff6..158743c64 100644 --- a/repoze/bfg/tests/test_zcml.py +++ b/repoze/bfg/tests/test_zcml.py @@ -57,7 +57,7 @@ class TestViewDirective(unittest.TestCase, PlacelessSetup): self.assertEqual(permission['args'][5], None) regadapt = actions[2] - regadapt_discriminator = ('view', IFoo, '', IRequest, IView) + regadapt_discriminator = ('view', IFoo, '', IRequest, IView, True) self.assertEqual(regadapt['discriminator'], regadapt_discriminator) self.assertEqual(regadapt['callable'], handler) self.assertEqual(regadapt['args'][0], 'registerAdapter') @@ -104,7 +104,34 @@ class TestViewDirective(unittest.TestCase, PlacelessSetup): self.assertEqual(permission['args'][5], None) regadapt = actions[2] - regadapt_discriminator = ('view', IFoo, '', IDummy, IView) + regadapt_discriminator = ('view', IFoo, '', IDummy, IView, True) + self.assertEqual(regadapt['discriminator'], regadapt_discriminator) + self.assertEqual(regadapt['callable'], handler) + self.assertEqual(regadapt['args'][0], 'registerAdapter') + self.assertEqual(regadapt['args'][1], view) + self.assertEqual(regadapt['args'][2], (IFoo, IDummy)) + self.assertEqual(regadapt['args'][3], IView) + self.assertEqual(regadapt['args'][4], '') + self.assertEqual(regadapt['args'][5], None) + + def test_uncacheable(self): + f = self._getFUT() + context = DummyContext() + class IFoo: + pass + def view(context, request): + pass + f(context, 'repoze.view', IFoo, view=view, request_type=IDummy, + cacheable=False) + actions = context.actions + from repoze.bfg.interfaces import IView + from zope.component.zcml import handler + from repoze.bfg.zcml import Uncacheable + + self.assertEqual(len(actions), 3) + + regadapt = actions[2] + regadapt_discriminator = ('view', IFoo, '', IDummy, IView, Uncacheable) self.assertEqual(regadapt['discriminator'], regadapt_discriminator) self.assertEqual(regadapt['callable'], handler) self.assertEqual(regadapt['args'][0], 'registerAdapter') @@ -180,6 +207,28 @@ class TestZCMLPickling(unittest.TestCase, PlacelessSetup): actions = cPickle.load(open(picklename, 'rb')) self.failUnless(actions) + def test_file_configure_uncacheable_removes_cache(self): + import os + from repoze.bfg.zcml import file_configure + picklename = os.path.join(self.packagepath, 'configure.zcml.cache') + f = open(picklename, 'w') + f.write('imhere') + self.failUnless(os.path.exists(picklename)) + + import repoze.bfg.zcml + keep_view = repoze.bfg.zcml.view + + def wrap_view(*arg, **kw): + kw['cacheable'] = False + return keep_view(*arg, **kw) + + try: + repoze.bfg.zcml.view = wrap_view + file_configure('configure.zcml', self.module) + self.failIf(os.path.exists(picklename)) # should be deleted + finally: + repoze.bfg.zcml.view = keep_view + def test_file_configure_nonexistent_configure_dot_zcml(self): import os from repoze.bfg.zcml import file_configure diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py index 4a0094dc3..a2a063603 100644 --- a/repoze/bfg/zcml.py +++ b/repoze/bfg/zcml.py @@ -22,12 +22,17 @@ from repoze.bfg.path import package_path from repoze.bfg.security import ViewPermissionFactory +class Uncacheable(object): + """ Include in discriminators of actions which are not cacheable """ + pass + def view(_context, permission=None, for_=None, view=None, name="", request_type=IRequest, + cacheable=True, ): if not view: @@ -43,7 +48,7 @@ def view(_context, if permission: pfactory = ViewPermissionFactory(permission) _context.action( - discriminator = ('permission', for_,name, request_type, + discriminator = ('permission', for_, name, request_type, IViewPermission), callable = handler, args = ('registerAdapter', @@ -51,8 +56,10 @@ def view(_context, _context.info), ) + cacheable = cacheable or Uncacheable + _context.action( - discriminator = ('view', for_, name, request_type, IView), + discriminator = ('view', for_, name, request_type, IView, cacheable), callable = handler, args = ('registerAdapter', view, (for_, request_type), IView, name, @@ -93,7 +100,7 @@ class IViewDirective(Interface): required=False ) -PVERSION = 0 +PVERSION = 1 def pickle_name(name, package): path = package_path(package) @@ -127,9 +134,9 @@ def zcml_configure(name, package, load=cPickle.load): files = set() for action in actions: - # files list used by pickled action is an element of the tuple try: - files.update(action[4]) + fileset = action[4] + files.update(fileset) except (TypeError, IndexError): return file_configure(name, package) @@ -145,6 +152,7 @@ def zcml_configure(name, package, load=cPickle.load): context = zope.configuration.config.ConfigurationMachine() xmlconfig.registerCommonDirectives(context) context.actions = actions + context.cached_execution = True context.execute_actions() return True @@ -159,6 +167,16 @@ def file_configure(name, package, dump=cPickle.dump): actions = context.actions pckname = pickle_name(name, package) + for action in actions: + + discriminator = action[0] + if discriminator and Uncacheable in discriminator: + try: + os.remove(pckname) + except: + pass + return False + try: data = (PVERSION, time.time(), actions) dump(data, open(pckname, 'wb'), -1) |
