[Grok-dev] Re: Making an interface the default module context
Philipp von Weitershausen
philipp at weitershausen.de
Mon Aug 4 04:22:31 EDT 2008
Martin Aspeli wrote:
>> Despite popular belief, grok doesn't actually use magic ;).
>
> Do you prefer to be called "illusionists"? :)
Yes, much better! :)
>> If you can somehow find a rule by which this interface is found, then
>> yes, it's possible. You'll have to override grokcore.component's
>> ContextGrokker which looks at the module, determines the implicit
>> module context and then uses the grok.context() directive to store
>> this implicit context so that it'll look to subsequent grokkers as if
>> grok.context() was used.
>>
>> So what you can do is write something like that:
>>
>> from grokcore.component.meta import ContextGrokker
>>
>> class MyContextGrokker(martian.GlobalGrokker):
>> # execute this grokker before grokcore.component's ContextGrokker
>> martian.priority(martian.priority.bind().get(ContextGrokker) + 1)
>>
>> def grok(self, name, module, module_info, config, **kw):
>> context = grok.context.bind().get(module=module)
>> if context is None:
>> # grok.context() wasn't used explicitly so let's try
>> # to find an implicit context by our rules and then
>> # set it
>> implicit_context = somehow_determine_from(module)
>> grok.context.set(module, implicit_context)
>>
>> All you now have to do is write this 'somehow_determine_from(module)'
>> algorithm that looks at a module and finds your IFoo.
>
> Maybe scan for something that provides IContext, if nothing implements it?
Sure, though I find it awkward having to write:
class IFoo(Schema):
pass
alsoProvides(IFoo, IContext)
If you're trying to find implicit contexts that are interfaces, it'd be
easier to look for interfaces that extend a certain interface, e.g. in
your case that Schema thing. Here's what that could look like:
def somehow_determine_from(module):
results = []
for name in dir(module):
obj = module.getattr(module)
if martian.util.defined_locally(obj, module.__name__):
# obj wasn't imported into the module, it was
# actually defined there
if IInterface.providedBy(obj) and obj.extends(Schema):
results.append(obj)
if not results:
return None
elif len(results) > 1:
return grokcore.component.scan.AMIBIGUOUS_COMPONENT
return results[0]
> I'm sure it can be done. My question is whether it's a good idea and
> something worth having in Grok itself.
Maybe. If the function above were generalized a bit, it could have a
place in grokcore.component or martian. We should see if this pattern
comes up more often, though, and if it actually solves your problem.
More information about the Grok-dev
mailing list