[Grok-dev] we need a MethodGrokker

Martijn Faassen faassen at startifact.com
Fri May 16 11:59:07 EDT 2008


Hi there,

Looking through Philipp's changes I think it becomes clear that we need 
a MethodGrokker, and what it could look like. I think a general goal we 
should have is to get rid of manual 'grok.directive.bind().get()' calls 
as much as possible in our codebase, in favor of a declarative approach.

Right now the XMLRPCGrokker, JSONGrokker and RESTGrokker are 
martian.ClassGrokker.

What they do is actually:

* pull out directives that are on the class level

* then loop through the methods

* get some extra directive informations that was placed on the method 
directly using a decorator (right now, that's just @grok.require)

* do the configuration actions.

I propose we introduce a MethodGrokker in Martian that automates parts 
of this for us. A MethodGrokker for XMLRPC could look like something like:

class XMLRPCGrokker(martian.MethodGrokker):

     component_class = grok.XMLRPC

     directives = [
         grok.context.bind(),
         grok.require.bind(), # should look at method, then class
         grok.name.bind(), # should get name of method
         ]

     def execute(self, factory, method, config, name, require, context, 
**kw):
         # make sure we issue an action to check whether this permission
         # exists. That's the only thing that action does
         if class_permission is not None:
             config.action(
                 discriminator=None,
                 callable=check_permission,
                 args=(factory, require)
                 )

         # Make sure that the class inherits MethodPublisher, so that the
         # views have a location
         method_view = type(
              factory.__name__, (factory, MethodPublisher),
              {'__call__': method}
              )

         adapts = (context, IXMLRPCRequest)
         config.action(
           discriminator=('adapter', adapts, interface.Interface, name),
           callable=component.provideAdapter,
           args=(method_view, adapts, interface.Interface, name),
           )

         config.action(
             discriminator=('protectName', method_view, '__call__'),
             callable=make_checker,
             args=(factory, method_view, permission),
             )
         return True

What it does is to do public_methods_from_class for all methods of 
component_class subclasses, and execute action for that.

Summary:

* get rid of the loop; this is part of the MethodGrokker

* gets both factory and method as arguments, as we may need both.

* automate the defaulting behavior from method -> class, like we can 
already do it for class -> module

* let grok.name directive work here, which opens the door for a future 
@grok.name() decorator that works on methods too

* note that the original XMLRPCGrokker only did the check_permission for 
the class-level permission, we do it for all permissions (also the 
directive level permissions). You'd think that would be the right thing, 
but perhaps there's some subtlety that the tests cover that I forgot 
about. There's a performance argument in not doing it for permissions 
multiple times though, but we already didn't do this for class-level 
permissions.

I'm of course hand-waving some details. Philipp, others, opinions?

Regards,

Martijn



More information about the Grok-dev mailing list