[Checkins] SVN: grok/branches/0.11/ Backport fix for not
registering methods with names that
Jan-Wijbrand Kolman
janwijbrand at gmail.com
Mon Jan 7 10:27:06 EST 2008
Log message for revision 82731:
Backport fix for not registering methods with names that
start with an '_' as views on REST, XMLRPC and JSON components.
Changed:
U grok/branches/0.11/CHANGES.txt
U grok/branches/0.11/src/grok/meta.py
U grok/branches/0.11/src/grok/tests/json/view_lookup.py
A grok/branches/0.11/src/grok/tests/util/public_methods_from_class.py
U grok/branches/0.11/src/grok/util.py
-=-
Modified: grok/branches/0.11/CHANGES.txt
===================================================================
--- grok/branches/0.11/CHANGES.txt 2008-01-07 15:20:52 UTC (rev 82730)
+++ grok/branches/0.11/CHANGES.txt 2008-01-07 15:27:05 UTC (rev 82731)
@@ -7,6 +7,12 @@
Bug fixes
---------
+* Do not register the publishTraverse and browserDefault methods of the
+ JSON component as views.
+
+* Methods with names that start with an '_' are not registered as views
+ for XMLRPC, REST and JSON components.
+
* Use a configuration action for the registration of the static directory.
* Fix https://bugs.launchpad.net/grok/+bug/161948: grok.testing.grok()
Modified: grok/branches/0.11/src/grok/meta.py
===================================================================
--- grok/branches/0.11/src/grok/meta.py 2008-01-07 15:20:52 UTC (rev 82730)
+++ grok/branches/0.11/src/grok/meta.py 2008-01-07 15:27:05 UTC (rev 82731)
@@ -47,7 +47,7 @@
import grok
from grok import components, formlib, templatereg
from grok.util import check_adapts, get_default_permission, make_checker
-from grok.util import determine_class_directive
+from grok.util import determine_class_directive, public_methods_from_class
from grok.rest import RestPublisher
from grok.interfaces import IRESTSkinType
@@ -130,10 +130,9 @@
def grok(self, name, factory, module_info, config, **kw):
context = module_info.getAnnotation('grok.context', None)
view_context = util.determine_class_context(factory, context)
- # XXX We should really not make __FOO__ methods available to
- # the outside -- need to discuss how to restrict such things.
- methods = util.methods_from_class(factory)
+ methods = public_methods_from_class(factory)
+
default_permission = get_default_permission(factory)
for method in methods:
@@ -174,10 +173,9 @@
def grok(self, name, factory, module_info, config, **kw):
context = module_info.getAnnotation('grok.context', None)
view_context = util.determine_class_context(factory, context)
- # XXX We should really not make __FOO__ methods available to
- # the outside -- need to discuss how to restrict such things.
- methods = util.methods_from_class(factory)
+ methods = public_methods_from_class(factory)
+
default_permission = get_default_permission(factory)
# grab layer from class or module
@@ -294,11 +292,19 @@
def grok(self, name, factory, module_info, config, **kw):
context = module_info.getAnnotation('grok.context', None)
view_context = util.determine_class_context(factory, context)
- methods = util.methods_from_class(factory)
+ methods = public_methods_from_class(factory)
+
default_permission = get_default_permission(factory)
for method in methods:
+ # The grok.JSON component inherits methods from its baseclass
+ # (being zope.publisher.browser.BrowserPage) with names that
+ # do not start with an underscore, but should still not
+ # be registered as views. Ignore these methods:
+ if method.__name__ in ['browserDefault', 'publishTraverse']:
+ continue
+
# Create a new class with a __view_name__ attribute so the
# JSON class knows what method to call.
method_view = type(
Modified: grok/branches/0.11/src/grok/tests/json/view_lookup.py
===================================================================
--- grok/branches/0.11/src/grok/tests/json/view_lookup.py 2008-01-07 15:20:52 UTC (rev 82730)
+++ grok/branches/0.11/src/grok/tests/json/view_lookup.py 2008-01-07 15:27:05 UTC (rev 82731)
@@ -20,7 +20,44 @@
>>> view = getMultiAdapter((mammoth, request), name='another')
>>> view()
'{"another": "grok"}'
-
+
+Although principally all methods of the JSON class are registered as views,
+methods with names that start with an underscore are not::
+
+ >>> view = getMultiAdapter((mammoth, request), name='_private')
+ Traceback (most recent call last):
+ ...
+ ComponentLookupError: ((<grok.tests.json.view_lookup.Mammoth object at ...>,
+ <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1>),
+ <InterfaceClass zope.interface.Interface>, '_private')
+
+Even more important, special methods like __call__ are not registered as viewws
+too. This test is here to make sure a previous bug has been fixed::
+
+ >>> view = getMultiAdapter((mammoth, request), name='__call__')
+ Traceback (most recent call last):
+ ...
+ ComponentLookupError: ((<grok.tests.json.view_lookup.Mammoth object at ...>,
+ <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1>),
+ <InterfaceClass zope.interface.Interface>, '__call__')
+
+For JSON views we also need to confirm some methods that are defined on the
+baseclass (BrowserPage) are not registered as views::
+
+ >>> view = getMultiAdapter((mammoth, request), name='browserDefault')
+ Traceback (most recent call last):
+ ...
+ ComponentLookupError: ((<grok.tests.json.view_lookup.Mammoth object at ...>,
+ <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1>),
+ <InterfaceClass zope.interface.Interface>, 'browserDefault')
+
+ >>> view = getMultiAdapter((mammoth, request), name='publishTraverse')
+ Traceback (most recent call last):
+ ...
+ ComponentLookupError: ((<grok.tests.json.view_lookup.Mammoth object at ...>,
+ <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1>),
+ <InterfaceClass zope.interface.Interface>, 'publishTraverse')
+
"""
import grok
@@ -35,4 +72,9 @@
def another(self):
return { 'another': 'grok'}
-
+
+class SecondMammothView(grok.JSON):
+ grok.context(Mammoth)
+
+ def _private(self):
+ return {'should': 'not be registered'}
Added: grok/branches/0.11/src/grok/tests/util/public_methods_from_class.py
===================================================================
--- grok/branches/0.11/src/grok/tests/util/public_methods_from_class.py (rev 0)
+++ grok/branches/0.11/src/grok/tests/util/public_methods_from_class.py 2008-01-07 15:27:05 UTC (rev 82731)
@@ -0,0 +1,28 @@
+"""
+ >>> methods = grok.util.public_methods_from_class(A)
+ >>> sorted([m.__name__ for m in methods])
+ ['should_also_be_public', 'should_be_public']
+
+"""
+import grok
+import grok.util
+
+class A(object):
+
+ def __init__(self):
+ pass # this method is ignored
+
+ def __call__(self):
+ pass # this method is ignored
+
+ def __double_underscored(self):
+ pass # this method is ignored
+
+ def _single_underscored(self):
+ pass # this method is ignored
+
+ def should_be_public(self):
+ pass # this method is found
+
+ def should_also_be_public(self):
+ pass # this method is found
Modified: grok/branches/0.11/src/grok/util.py
===================================================================
--- grok/branches/0.11/src/grok/util.py 2008-01-07 15:20:52 UTC (rev 82730)
+++ grok/branches/0.11/src/grok/util.py 2008-01-07 15:27:05 UTC (rev 82731)
@@ -25,7 +25,7 @@
from zope.security.interfaces import IPermission
from martian.error import GrokError, GrokImportError
-from martian.util import class_annotation
+from martian.util import class_annotation, methods_from_class
def check_adapts(class_):
if component.adaptedBy(class_) is None:
@@ -105,3 +105,7 @@
if directive is not None:
return directive
return default
+
+def public_methods_from_class(factory):
+ return [m for m in methods_from_class(factory) if \
+ not m.__name__.startswith('_')]
More information about the Checkins
mailing list