|
View:
New views
12 Messages
—
Rating Filter:
Alert me
|
|
|
Making an interface the default module contextHi,
Let's say I have a module like: ... class IFoo(Schema): pass class FooView(grok.View): grok.require('hello') Here, Schema is imported from elsewhere, and is just a marker interface, i.e.: class Schema(Interface): pass Schema exists purely to make IFoo above grokkable with some optional directives. In the example above, I'd hoped that the context for FooView would default to IFoo if there was no other obvious context (e.g. a model). IFoo could be a marker interface, for example, which espouses a new view. However, FooView does not know its context, so I have to use grok.context(). I tried to let Schema provide IContext, and also to let IFoo provide IContext explicitly via alsoProvides(). Neither seems to stick. Is it possible to infer that the context for FooView should be IFoo in this case? Martin -- Author of `Professional Plone Development`, a book for developers who want to work with Plone. See http://martinaspeli.net/plone-book _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: Making an interface the default module contextMartin Aspeli wrote:
> Let's say I have a module like: > > ... > > class IFoo(Schema): > pass > > class FooView(grok.View): > grok.require('hello') > > Here, Schema is imported from elsewhere, and is just a marker interface, > i.e.: > > class Schema(Interface): > pass > > Schema exists purely to make IFoo above grokkable with some optional > directives. > > In the example above, I'd hoped that the context for FooView would > default to IFoo if there was no other obvious context (e.g. a model). Despite popular belief, grok doesn't actually use magic ;). > IFoo could be a marker interface, for example, which espouses a new view. > > However, FooView does not know its context, so I have to use > grok.context(). I tried to let Schema provide IContext, and also to let > IFoo provide IContext explicitly via alsoProvides(). Neither seems to > stick. If grok.context() isn't present it looks for something that *implements* IContext, not provides. > Is it possible to infer that the context for FooView should be IFoo in > this case? 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. _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: Making an interface the default module contextPhilipp von Weitershausen wrote:
> Martin Aspeli wrote: >> Let's say I have a module like: >> >> ... >> >> class IFoo(Schema): >> pass >> >> class FooView(grok.View): >> grok.require('hello') >> >> Here, Schema is imported from elsewhere, and is just a marker interface, >> i.e.: >> >> class Schema(Interface): >> pass >> >> Schema exists purely to make IFoo above grokkable with some optional >> directives. >> >> In the example above, I'd hoped that the context for FooView would >> default to IFoo if there was no other obvious context (e.g. a model). > > Despite popular belief, grok doesn't actually use magic ;). Do you prefer to be called "illusionists"? :) I'm not sure if this is borderline magic or not... I figured it was analogous to "the IContext-implementing class is the context". >> IFoo could be a marker interface, for example, which espouses a new view. >> >> However, FooView does not know its context, so I have to use >> grok.context(). I tried to let Schema provide IContext, and also to let >> IFoo provide IContext explicitly via alsoProvides(). Neither seems to >> stick. > > If grok.context() isn't present it looks for something that *implements* > IContext, not provides. Yes, I figured. >> Is it possible to infer that the context for FooView should be IFoo in >> this case? > > 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? I'm sure it can be done. My question is whether it's a good idea and something worth having in Grok itself. Martin -- Author of `Professional Plone Development`, a book for developers who want to work with Plone. See http://martinaspeli.net/plone-book _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: Making an interface the default module contextMartin 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. _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: Making an interface the default module contextPhilipp von Weitershausen <philipp <at> weitershausen.de> writes:
> If you're trying to find implicit contexts that are interfaces, it'd be > easier to look for interfaces that extend a certain interface How about looking for cases where either the interface or a base interface provides IContext? On a related note, I think it'd be nice to be able to do: class IFoo(Interface): grok.interface_provides(IContext) which would be equivalent ot class IFoo(Interface): pass alsoProvides(IFoo, IContext) > > 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. Agree. I think it's useful in the case where you want to provide a view or viewlet or adapter on a marker interface, certainly. On the other hand, it's not so hard to write grok.context(IFoo). :) Martin _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: Making an interface the default module contextMartin Aspeli wrote:
> Philipp von Weitershausen <philipp <at> weitershausen.de> writes: > >> If you're trying to find implicit contexts that are interfaces, it'd be >> easier to look for interfaces that extend a certain interface > > How about looking for cases where either the interface or a base interface > provides IContext? It seems easier to check if the interface extends IContext > On a related note, I think it'd be nice to be able to do: > > class IFoo(Interface): > grok.interface_provides(IContext) > > which would be equivalent ot > > class IFoo(Interface): > pass > alsoProvides(IFoo, IContext) I don't see the necessity to invent a syntax for this right now. >>> 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. > > Agree. I think it's useful in the case where you want to provide a view or > viewlet or adapter on a marker interface, certainly. > > On the other hand, it's not so hard to write grok.context(IFoo). :) Indeed. At least for Grok I personally don't have the intent of changing the implicit context rules. That doesn't mean you couldn't explore alternatives and enlighten us with some lessons learned :). For Grok I'd personally prefer a bit more conservatism right now. We *are* trying to get towards a 1.0 release, after all, and have other things on our list for that. _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: Making an interface the default module contextHey,
Just double-checking, but you do know about module-level use of grok.context(), right? Regards, Martijn _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: Making an interface the default module contextPhilipp von Weitershausen wrote:
[snip] > At least for Grok I personally don't have the intent of changing the > implicit context rules. That doesn't mean you couldn't explore > alternatives and enlighten us with some lessons learned :). For Grok I'd > personally prefer a bit more conservatism right now. We *are* trying to > get towards a 1.0 release, after all, and have other things on our list > for that. Agreed we should be careful here. That said, auto-associating with an interface that extends IContext sounds like a reasonable approach. It should of course fail in the face of ambiguity (a class *and* a model being around). This would introduce auto-association with interfaces. I think that's a reasonably safe behavior if we require that IContext is extended, and is more or less analogous to what happens with classes as far as I can see. Regards, Martijn _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: Making an interface the default module contextMartijn Faassen wrote:
> Hey, > > Just double-checking, but you do know about module-level use of > grok.context(), right? Nope. :-) I'm guessing that'd fix this, though. Martin -- Author of `Professional Plone Development`, a book for developers who want to work with Plone. See http://martinaspeli.net/plone-book _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: Making an interface the default module contextMartijn Faassen wrote:
> Philipp von Weitershausen wrote: > [snip] >> At least for Grok I personally don't have the intent of changing the >> implicit context rules. That doesn't mean you couldn't explore >> alternatives and enlighten us with some lessons learned :). For Grok >> I'd personally prefer a bit more conservatism right now. We *are* >> trying to get towards a 1.0 release, after all, and have other things >> on our list for that. > > Agreed we should be careful here. > > That said, auto-associating with an interface that extends IContext > sounds like a reasonable approach. It should of course fail in the face > of ambiguity (a class *and* a model being around). Of course. > This would introduce auto-association with interfaces. I think that's a > reasonably safe behavior if we require that IContext is extended, and is > more or less analogous to what happens with classes as far as I can see. Yeah. Well, if somebody's willing to extend grokcore.component as described here, I won't say no :). _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: Making an interface the default module contextPhilipp von Weitershausen wrote:
[snip] >> This would introduce auto-association with interfaces. I think that's >> a reasonably safe behavior if we require that IContext is extended, >> and is more or less analogous to what happens with classes as far as I >> can see. > > Yeah. Well, if somebody's willing to extend grokcore.component as > described here, I won't say no :). One thing I worry about is as this is an instance, it might auto-associate even with an imported interface. We need to make sure that this isn't the case. Regards, Martijn _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: Making an interface the default module contextMartijn Faassen wrote:
> Philipp von Weitershausen wrote: > [snip] >>> This would introduce auto-association with interfaces. I think that's >>> a reasonably safe behavior if we require that IContext is extended, >>> and is more or less analogous to what happens with classes as far as >>> I can see. >> >> Yeah. Well, if somebody's willing to extend grokcore.component as >> described here, I won't say no :). > > One thing I worry about is as this is an instance, it might > auto-associate even with an imported interface. We need to make sure > that this isn't the case. Indeed. martian's scan_for_classes wisely uses the defined_locally check for that. If it were extended to scan for interfaces as well, that check would have to be applied to them as well. All that said, in my experience apps quickly outgrow the restrictions that are required for using this automatic mapping of views and other adapters to implicit contexts. While it's great to have automatic mapping when you start out and just write a bunch of classes in one module, I find that when introduce interfaces, you tend to have so many components anyways that it's wise to split up the code over multiple modules. At that point you should also have understood what grok.context() does and why it's necessary. _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
| Free Forum Powered by Nabble | Forum Help |