Skip to content

Commit

Permalink
Fixed issue where multiple registrations that match the same request …
Browse files Browse the repository at this point in the history
…would fail in the sense that only one manager (picked randomly) would be allowed to check for an override.
  • Loading branch information
malthe committed Jan 9, 2012
1 parent 182b7cd commit f3cc37a
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 16 deletions.
9 changes: 9 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
Changes
=======

In next release ...

- Fixed an issue where multiple registrations against the same layer
would cause only one registration (decided randomly) to have effect.

The lookup code now uses the specification resolution order to query
for override registrations in order of specialization.
[malthe]

0.7 (2012-01-05)
----------------

Expand Down
9 changes: 8 additions & 1 deletion z3c/jbot/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ that it's registered for the same template manager.
>>> from z3c.jbot.metaconfigure import handler
>>> manager = handler("%s/overrides/interface" % directory, interface.Interface)

We make sure that the presence of an additional, trivial manager, does
not affect the result. We register the system temporary directory:

>>> import tempfile
>>> handler(tempfile.tempdir, interface.Interface)
<z3c.jbot.manager.TemplateManager object at ...>

We should now see that the new filename will be used for rendering:

>>> view.template()
Expand Down Expand Up @@ -194,7 +201,7 @@ Providing the HTTP-request layer does not change this.

Unregister overrides.

>>> for manager in z3c.jbot.utility.getManagers():
>>> for manager in z3c.jbot.utility.getManagers(IHTTPRequest):
... manager.unregisterAllDirectories()

>>> view.template()
Expand Down
2 changes: 1 addition & 1 deletion z3c/jbot/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def registerTemplate(self, template, token):
filename = path.replace(os.path.sep, '.')
if filename not in paths:
self.templates[token] = IGNORE
return True
return

path = paths[filename]

Expand Down
4 changes: 2 additions & 2 deletions z3c/jbot/patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def get(template, view=None, cls=None):
inst = registry[key] = cls.__new__(cls)
inst.__dict__ = template.__dict__.copy()

for manager in utility.getManagers():
for manager in utility.getManagers(layer):
# register template; this call returns ``True`` if the
# template was invalidated (changed filename)
if manager.registerTemplate(inst, template):
Expand Down Expand Up @@ -109,7 +109,7 @@ def get_skin_obj(obj, view=None, cls=None):
inst = registry[key] = cls.__new__(cls)
inst.__dict__ = obj.__dict__.copy()

for manager in utility.getManagers():
for manager in utility.getManagers(layer):
# register template; this call returns ``True`` if the
# template was invalidated (changed filename)
if manager.registerTemplate(inst, obj):
Expand Down
20 changes: 20 additions & 0 deletions z3c/jbot/tests/common.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import shutil
import tempfile

import zope.component.testing
import zope.configuration.xmlconfig

Expand All @@ -15,3 +18,20 @@ def setUp(test):
pass
else:
zope.configuration.xmlconfig.XMLConfig('configure.zcml', five.pt)()

test.tempdir = tempfile.tempdir
tempfile.tempdir = tempfile.mkdtemp()


def tearDown(test):
zope.component.testing.tearDown(test)

try:
tempdir = test.tempdir
except AttributeError:
pass
else:
try:
shutil.rmtree(tempfile.tempdir)
finally:
tempfile.tempdir = tempdir
3 changes: 2 additions & 1 deletion z3c/jbot/tests/test_doctests.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
zope.testing.doctest.NORMALIZE_WHITESPACE)

from common import setUp
from common import tearDown


def test_suite():
Expand All @@ -19,7 +20,7 @@ def test_suite():
'README.txt',
optionflags=OPTIONFLAGS,
setUp=setUp,
tearDown=zope.component.testing.tearDown,
tearDown=tearDown,
globs=globs,
package="z3c.jbot"),
))
Expand Down
39 changes: 28 additions & 11 deletions z3c/jbot/utility.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from zope import interface
from zope import component
from zope.interface import Interface
from zope.interface import providedBy
from zope.component import getGlobalSiteManager

try:
from zope.site.hooks import getSite
Expand All @@ -11,14 +12,16 @@
import zope.security.management
import zope.security.interfaces

import interfaces
from z3c.jbot.interfaces import ITemplateManager


try:
import Acquisition
ZOPE_2 = True
except:
ZOPE_2 = False


def getRequest():
if ZOPE_2:
# get request by acquisition
Expand All @@ -38,18 +41,32 @@ def getRequest():
if IRequest.providedBy(p):
return p


def getLayer():
request = getRequest()

if request is not None:
return interface.providedBy(request)
return providedBy(request)

return Interface


def getManagers(layer):
try:
adapters = getGlobalSiteManager().adapters._adapters[1]
except IndexError:
return

for iface in layer.__sro__:
by_interface = adapters.get(iface)

return interface.Interface
if by_interface is not None:
managers = by_interface.get(ITemplateManager)

def getManagers():
layer = getLayer()
gsm = component.getGlobalSiteManager()
if managers is not None:
items = managers.items()
if len(items) > 1:
items = sorted(items)

for name, factory in reversed(
gsm.adapters.lookupAll((layer,), interfaces.ITemplateManager)):
yield factory(layer)
for name, factory in items:
yield factory(layer)

0 comments on commit f3cc37a

Please sign in to comment.