Re: [Repoze-dev] repoze.plugin documentation
On 4/29/09 4:32 PM, Ian Bicking wrote: > Some questions that come to mind: > > When I was discussing cases like this with Rob Miller, we also found most > plausible pluggability points required specific configuration. For this > example there's the client_templates value. You could possibly have a more > generic pluggable component that took configuration > "/site/client_templates/${client_slug}/${template_name}.html" and did > substitution, making it more loosely bound to the particular urlvars you > define. But regardless, configuration that is specific to both the > deployment and the specific registered implementation seems essential, and I > believe should be a first-class patter. > > Also, at least half the time or more I think a function is going to be > registered. There seems to be a class bias in several places, though maybe > I'm misreading that. > > An ambiguity: for this case, do you plug in the render function, a > load_template function, a function that calculates template_name...? Each > seems plausible, but the ambiguity is a bit purturbing. Deciding on any applictation-specific pluggability strategy is pretty hard. I don't have any good answers to your thoughts above because you're plugging things into other things that have no analogue in my development world (template loaders, for example). And in reality, I probably shouldn't need to care about the minutiae of those unless I'm your client and you've sliced and diced the application "just so" so I can't screw things up and you've documented all those plugpoints. But FWIW trying to anticipate pluggability by building very granular plugpoints into app code itself can often be avoided entirely if you provide "big hammer" mechanisms that allow clients to override behavior. Instead of trying to anticipate the client's every override requirement, you just let them register new "routes" (or whatever they use for URL dispatch) that point at entirely different controllers from outside an existing application, overriding routes that are already present in the application. Routes (the "proper" Routes), as used in Pylons *already* makes you specify the controller you want to use as one of its vars (at least in the most common case); you'd just take advantage of that by allowing it to be overridden. This is a heavy-hammer, least-effort, dumb-as-a-rock way of providing pluggability to an application. The use case is: "I don't really like the controller that route resolves to; I'll just replace it wholesale, logic, template loading, templates, and all". It's not very granular, but it's quite easy to explain. You don't need to torture yourself over where the plug points are: the application already exposes "natural" ones via controllers and routes (or whatever analogues for those things your own app has). - C ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
On Wed, Apr 29, 2009 at 1:35 AM, Chris McDonough wrote: > > I think we should reconsider the way we decide on views and related > > components. Perhaps using a routes-like approach, e.g. > > > > >... > >for=".interfaces.IHelpCenter .interfaces.IDocument" > >/> > > > > (to target documents inside the help center section). Or whatever > > language/abstraction that can fit the bill. Note that to match this > > "for" clause, something more than a simple component lookup is > > required. > > A fish doesnt know from wet, but I think if you were to want to go after > some > dispatch like this, you might as well just use some URL dispatch thing like > Routes itself, because it ties the traversal path (at least in some > abstract > sense) to a view. And once you do that, you might as well just use a regex > against the path itself to make it more flexible. OK, so this finally made me think of a place where Routes pluggability seems sensible. (I think a predecessor to repoze.plugin was Chris thinking about how Routes might be pluggable ala ZCA -- but we never came up with a use case for that pluggability.) Anyway, I could imagine the desire to, say, mark a set of pages/routes with a variable that isn't exactly used for routing. For instance: map.connect('/help', controller='help', template_path=site_templates) map.connect('/docs', controller='docs', template_path=site_templates) Then somewhere else you might have: def render(template_name, **kw): req = get_request() path = req.urlvars.get('template_path', standard_template_path) tmpl = load_template(os.path.join(path, template_name+'.html')) ... So it makes sense to make that pluggable. Except... you don't actually want to plug the Routes, because the routes for the application might not have any relation to the template paths you have. Instead you might just want to annotate the request, which I guess is what Tres is suggesting with repoze.uripace. OK, but here's a more serious pluggability thought. Let's say there aren't static routes you want to capture. Let's say you have a structure like /client/{client_slug}/ticket/1, and you want to allow clients to overload templates. You might want to instead do: def client_render(template_name, **kw): req = get_request() path = os.path.join(client_templates, req.urlvars.get('client_slug', 'default'), template_name+'.html') if not os.path.exists(path): path = os.path.join(standard_template_path, template_name+'.html') tmpl = load_template(...)... And then you want to register and configure this template loader, and presumably the framework or application uses: def render(template_name, **kw): renderer = registry.lookup('template_renderer') return renderer(template_name, **kw) This stubby indirection is kind of lame, but you don't very well want every code path to have to grab a template_renderer, it's better to import this one render function. Some questions that come to mind: When I was discussing cases like this with Rob Miller, we also found most plausible pluggability points required specific configuration. For this example there's the client_templates value. You could possibly have a more generic pluggable component that took configuration "/site/client_templates/${client_slug}/${template_name}.html" and did substitution, making it more loosely bound to the particular urlvars you define. But regardless, configuration that is specific to both the deployment and the specific registered implementation seems essential, and I believe should be a first-class patter. Also, at least half the time or more I think a function is going to be registered. There seems to be a class bias in several places, though maybe I'm misreading that. An ambiguity: for this case, do you plug in the render function, a load_template function, a function that calculates template_name...? Each seems plausible, but the ambiguity is a bit purturbing. -- Ian Bicking | http://blog.ianbicking.org ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Chris McDonough wrote: > On 4/28/09 3:01 AM, Malthe Borch wrote: >> I think we should reconsider the way we decide on views and related >> components. Perhaps using a routes-like approach, e.g. >> >>>... >>for=".interfaces.IHelpCenter .interfaces.IDocument" >>/> >> >> (to target documents inside the help center section). Or whatever >> language/abstraction that can fit the bill. Note that to match this >> "for" clause, something more than a simple component lookup is >> required. > > A fish doesnt know from wet, but I think if you were to want to go after some > dispatch like this, you might as well just use some URL dispatch thing like > Routes itself, because it ties the traversal path (at least in some abstract > sense) to a view. And once you do that, you might as well just use a regex > against the path itself to make it more flexible. Or use something like repoze.uripace which does the "pattern match" against the path and adds keys to the environment. Hmm, we might extend the request factory to use those keys to establish the marker interface / "layer" of the request. Tres. - -- === Tres Seaver +1 540-429-0999 tsea...@palladion.com Palladion Software "Excellence by Design"http://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFJ+Fvc+gerLs4ltQ4RAuPXAKCZwDM1n16XSsI2JgABlZltQkV6cACdERBX E67sTWAmuu8NGKrkPWeHBLo= =BVkg -END PGP SIGNATURE- ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
On Apr 27, 2009, at 1:31 PM, Reed O'Brien wrote: On Apr 27, 2009, at 1:18 PM, Chris McDonough wrote: I'm actually having a bit of trouble naming those things. At first they were called "plugin types", then "provides types", then finally "component types". None of those names really work for me. Why not just markers? or in the spirit of plugs, prongs For whatever reason this has been stuck in my head... In Erlang they refer to protocol pattern abstractions as 'behaviours'. Perhaps that is good candidate here, as well. ~ro smime.p7s Description: S/MIME cryptographic signature ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
2009/4/29 Chris McDonough : > That seems completely broken to me. It also doesn't match my (limited) > experience but I've never fought with it hard enough to know. That should have read: adaptation is like an alphabet: ABZ ABC ZBC > The real problem with doing the more clever thing is that it's just too hard > for any actual human to know what's going to happen. And the only real way > to fix that is to simplify the implementation, IMO. Indicators like "+" in > front of interface names makes me think of: > > #div { > color: blue !important > } > > .. and we all know how fun that is. Hey, I... fine. \malthe ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
On 4/29/09 3:07 AM, Malthe Borch wrote: > 2009/4/29 Chris McDonough: >> If this really is due to the wildcard thing: IMO, zope.component should >> probably >> try to match any lookup against wildcard registrations dead last. I'm sorta >> surprised it doesn't. > > It does it in-order with adapters queried in order of specialization; > but adapters that are specialized come in last. That seems completely broken to me. It also doesn't match my (limited) experience but I've never fought with it hard enough to know. >> But in general, interface inheritance seems pretty evil. I'd rather that it >> just composed the "requires" interfaces by looking up the MRO of the >> instance and its base classes rather than combining that with the concept of >> an "iro". > > This again comes with an idea of "availability" I think; it might be > that your adapter is more specialized, but it also claims to implement > its iro. I just had a bad flashback: "DTML expression lookup rules". >> I think maybe the right thing to do there (if we can't fix it) is to just >> repeat ourselves in configuration. > > Yes; or as in my example, resort to registering "normal" views for > ``IGetRequest``. It's probably good practice anyway. The real problem with doing the more clever thing is that it's just too hard for any actual human to know what's going to happen. And the only real way to fix that is to simplify the implementation, IMO. Indicators like "+" in front of interface names makes me think of: #div { color: blue !important } .. and we all know how fun that is. - C ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
2009/4/29 Chris McDonough : > If this really is due to the wildcard thing: IMO, zope.component should > probably > try to match any lookup against wildcard registrations dead last. I'm sorta > surprised it doesn't. It does it in-order with adapters queried in order of specialization; but adapters that are specialized come in last. > But in general, interface inheritance seems pretty evil. I'd rather that it > just composed the "requires" interfaces by looking up the MRO of the > instance and its base classes rather than combining that with the concept of > an "iro". This again comes with an idea of "availability" I think; it might be that your adapter is more specialized, but it also claims to implement its iro. > I think maybe the right thing to do there (if we can't fix it) is to just > repeat ourselves in configuration. Yes; or as in my example, resort to registering "normal" views for ``IGetRequest``. It's probably good practice anyway. \malthe ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
On 4/29/09 2:41 AM, Malthe Borch wrote: > 2009/4/29 Chris McDonough: >> When you do need it, the multiplexing is awful handy (e.g. when trying to >> look up a view based on a context type and a request type). > > Except there's always this situation: > > View 1) > >for="IDocument IRequest" > > View 2) > >for="Interface IPostRequest" > > Let's say that you wanted always to do something special for POST > requests. This won't work; you have to change (1) to > >for="IDocument IGetRequest" I'll take your word for it. Who the hell knows how that works? This is due to the "Interface" wildcard? I just never try to do anything this complicated. I'd just do: view 1) for="IDocument IRequest" view 2) for="IDocument IPOSTRequest" and I'd repeat that for any "context" type that I also wanted to adapt on. If this really is due to the wildcard thing: IMO, zope.component should probably try to match any lookup against wildcard registrations dead last. I'm sorta surprised it doesn't. But in general, interface inheritance seems pretty evil. I'd rather that it just composed the "requires" interfaces by looking up the MRO of the instance and its base classes rather than combining that with the concept of an "iro". > I find that the ordering of multi-adaptation hinders me in using them > in a clean way; perhaps the solution is to have some kind of priority > token, e.g. > >for="Interface +IPostRequest" > > You can argue that anything more than we have now is too complex; > still, for multiplexing, the default adaptation ordering isn't always > desirable. I think maybe the right thing to do there (if we can't fix it) is to just repeat ourselves in configuration. - C ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
2009/4/29 Chris McDonough : > In the second view variant, the unit test indirection would need to be > registered in ZCML or elsewhere. In the first one, it needn't be, except > within the unit test itself. The main benefit of this is that registrations > made only to service unit tests don't need to pollute ZCML. That's an interesting approach; it beats default component registration in a "configure.zcml" file since it's a) clearly understandable from code what implementation gets used and b) easy to override (by actually registering a component). It reminds me of something daniel nouri did in his singing & dancing packages, a la: @property def some_property(self): return getUtility(ISomeUtility) It's encouraged in these packages to set persistent utilities (or what-not) on instances of the classes, effectively overriding the default properties which defer to component lookup. \malthe ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
One of the epiphanies Tres came up with during a bout of drinking is that the #1 navel-gaze below (the unittest indirection one) doesn't need a ZCML registration (or any "real" component registrations at all except in the unit test). Instead, to do unit testing indirection, say for a test like so: def test_it(self): from something import view context = DummyContext() request = DummyRequest() result = view(context, request) def factory(context, request): return DummyImplementation() provideAdapter(factory, (None, None), ISomeUnitTestIndirection) self.assertEqual(result.status, '200 OK') Where the 'from something import view' might resolve to: def view(context, request): impl = queryMultiAdapter((context, request), ISomeUnitTestIndirection) if impl is None: impl = TheRealImplementation(context, request) return Response(impl.render()) This is as opposed to doing: def view(context, request): impl = getMultiAdapter((context, request), ISomeUnitTestIndirection) In the second view variant, the unit test indirection would need to be registered in ZCML or elsewhere. In the first one, it needn't be, except within the unit test itself. The main benefit of this is that registrations made only to service unit tests don't need to pollute ZCML. - C On 4/27/09 2:56 PM, Chris McDonough wrote: > On 4/27/09 1:18 PM, Chris McDonough wrote: >>> I find the introduction lacking; why do I care about indirection, >>> what's the benefit. >> Good point. >> >> Um. Why *do* we care about indirection? In particular, why do we care about >> this sort of generic-function-ish dispatch pattern we call adaptation? Why >> do >> we care about it for *every* application? I'm too brainwashed to answer that >> question without thinking about views. If we want something to be bit off by >> the larger Python community, we need an answer for this. > > Answering myself with the kind of navel-gazing which is sure to drive Tres > nuts ;-): > > - We use the heck out of indirections during unit testing. In most > of the apps I write personally, the ZCA indirections are the only thing > that make it *possible* to write unit tests rather than needing > to write functional tests. But typically during testing the idea that > some *adapter* is registered against more than one "requires" interface is > just something that we deal with rather something that is actively > desirable (because we always only have one implementation during > unit testing); the actual multidispatch is to support the below > case. > > - We use adaptation and utility indirections in applications to allow > people to override implementations without needing to change the code. > Most non-Zope people associate this desire to provide pluggability, > correctly or incorrectly, with "CMS" systems. But there's something > to this conclusion because indeed the ZCA indirections were originally > meant to replace use of something like acquisition to find values in > "content space". I suspect we are quite brainwashed here, or at > least incapable of discounting this use case, because we tend to > treat every application as something that might turn into a framework. > > - We use utility indirections (or at least I do) to retrieve > application-specific configuration values (e.g. BFG's ISettings > utility, which offers no behavior except as a bag-of-names). > > I have some ideas about how you might layer several systems together to allow > people to only bite off one bit of software for each of these cases. #2 is > the > most problematic and would be at a higher layer. > > - C > > ___ > Repoze-dev mailing list > Repoze-dev@lists.repoze.org > http://lists.repoze.org/listinfo/repoze-dev > ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
2009/4/29 Chris McDonough : > When you do need it, the multiplexing is awful handy (e.g. when trying to > look up a view based on a context type and a request type). Except there's always this situation: View 1) for="IDocument IRequest" View 2) for="Interface IPostRequest" Let's say that you wanted always to do something special for POST requests. This won't work; you have to change (1) to for="IDocument IGetRequest" I find that the ordering of multi-adaptation hinders me in using them in a clean way; perhaps the solution is to have some kind of priority token, e.g. for="Interface +IPostRequest" You can argue that anything more than we have now is too complex; still, for multiplexing, the default adaptation ordering isn't always desirable. \malthe ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
On 4/28/09 3:01 AM, Malthe Borch wrote: > 2009/4/27 Chris McDonough: >> Answering myself with the kind of navel-gazing which is sure to drive Tres >> nuts ;-): > > Not answering anything, but this thread is as good a place as any: > > I think the issue of overriding default components is unnatural. > Rather, I'd like to think of components in terms of availability, > rather than pluggability. Concretely, the following is *pluggability*: > >>>> by_interface = {} > > Plug me once, you'll plug something out if you try it again. > > That's not what the ZCA is about; I think it's rather about > availability, e.g. if I give you these N things, give me something > that provides some formal functionality (described by an interface). > The problem with this line of thought is that it breaks down when you > abuse it to multiplex user interface elements; because here it's not > about availability, it's about multiplexing. When you do need it, the multiplexing is awful handy (e.g. when trying to look up a view based on a context type and a request type). > I think we should reconsider the way we decide on views and related > components. Perhaps using a routes-like approach, e.g. > >... >for=".interfaces.IHelpCenter .interfaces.IDocument" >/> > > (to target documents inside the help center section). Or whatever > language/abstraction that can fit the bill. Note that to match this > "for" clause, something more than a simple component lookup is > required. A fish doesnt know from wet, but I think if you were to want to go after some dispatch like this, you might as well just use some URL dispatch thing like Routes itself, because it ties the traversal path (at least in some abstract sense) to a view. And once you do that, you might as well just use a regex against the path itself to make it more flexible. - C ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
2009/4/28 Chris Rossi : >> ``zope.component.getAllUtilitiesFor`` does that. Might be called ``getAllUtilitiesRegisteredFor``, although there's another variant, too, ``getUtilitiesFor``. \malthe ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
On Tue, Apr 28, 2009 at 9:56 AM, Malthe Borch wrote: > > > ``zope.component.getAllUtilitiesFor`` does that. > > Awesome! Chris ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
2009/4/28 Chris Rossi : >> (to target documents inside the help center section). Or whatever >> language/abstraction that can fit the bill. Note that to match this >> "for" clause, something more than a simple component lookup is >> required. >> > I'm not sure that I see the need for that personally, but maybe it just > hasn't sunk in yet why I'd want to do that. Just today, someone asked the question of how to register a "viewlet" (is that a legal word on the mailinglist?) such that it appeared in some section and below. I think that's a problem that's harder than it should be; certainly we're familiar with the notion of "this element and below" in the DOM; why can't we have the same notion for the object hierarchy? >>> registry.look("img_processor") > { 'Fuzzy Clouds': , > 'Satanic Request': , > 'Greenery Plugin': , > etc... > } ``zope.component.getAllUtilitiesFor`` does that. \malthe ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
On Tue, Apr 28, 2009 at 3:01 AM, Malthe Borch wrote: > 2009/4/27 Chris McDonough : > > Answering myself with the kind of navel-gazing which is sure to drive > Tres > > nuts ;-): > > Not answering anything, but this thread is as good a place as any: > > I think the issue of overriding default components is unnatural. > Rather, I'd like to think of components in terms of availability, > rather than pluggability. Concretely, the following is *pluggability*: > > >>> by_interface = {} > > Plug me once, you'll plug something out if you try it again. > > That's not what the ZCA is about; I think it's rather about > availability, e.g. if I give you these N things, give me something > that provides some formal functionality (described by an interface). > The problem with this line of thought is that it breaks down when you > abuse it to multiplex user interface elements; because here it's not > about availability, it's about multiplexing. > > I think we should reconsider the way we decide on views and related > components. Perhaps using a routes-like approach, e.g. > >... > for=".interfaces.IHelpCenter .interfaces.IDocument" > /> > > (to target documents inside the help center section). Or whatever > language/abstraction that can fit the bill. Note that to match this > "for" clause, something more than a simple component lookup is > required. > > I'm not sure that I see the need for that personally, but maybe it just hasn't sunk in yet why I'd want to do that. I did want to go ahead and bring up a completely different use case that is very common in the wild but doesn't seem to be addressed in ZCA or this generic formulation. Let's call it the Photoshop model, since hopefully everyone knows what Photoshop plugins are. You have N number of plugins that define a particular interface that are all registered but with no preferential treatment in terms of look up--just a list of things you could possibly use, with choice driven by the user. >>> registry.look("img_processor") [ , , , etc...] or maybe a dict, more like: >>> registry.look("img_processor") { 'Fuzzy Clouds': , 'Satanic Request': , 'Greenery Plugin': , etc... } Now, I have no idea whether or not we actually care about this use case. An application that uses plugins like this could easily define it's registry and registration process. But, it had occurred to me, that if you're throwing around the word plugin to people not already familiar with ZCA, a lot of people are going to be thinking this model. Chris ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
2009/4/27 Chris McDonough : > Answering myself with the kind of navel-gazing which is sure to drive Tres > nuts ;-): Not answering anything, but this thread is as good a place as any: I think the issue of overriding default components is unnatural. Rather, I'd like to think of components in terms of availability, rather than pluggability. Concretely, the following is *pluggability*: >>> by_interface = {} Plug me once, you'll plug something out if you try it again. That's not what the ZCA is about; I think it's rather about availability, e.g. if I give you these N things, give me something that provides some formal functionality (described by an interface). The problem with this line of thought is that it breaks down when you abuse it to multiplex user interface elements; because here it's not about availability, it's about multiplexing. I think we should reconsider the way we decide on views and related components. Perhaps using a routes-like approach, e.g. (to target documents inside the help center section). Or whatever language/abstraction that can fit the bill. Note that to match this "for" clause, something more than a simple component lookup is required. \malthe ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
Hey, On Mon, Apr 27, 2009 at 6:19 AM, Malthe Borch wrote: > I realize this documentation[1] is still in progress; yet, here are > some comments, posted to the list to maybe encourage some kind of > debate (since it's likely that there will be several consumers of this > package in repoze.* in the future: > > I find the introduction lacking; why do I care about indirection, > what's the benefit. > > Next, I can't read through the documentation if it's going to be all > "a" and "somecomponent"; can we have some kind of context, e.g. a > story-line or some likely scenario. This would help a lot in > motivating the package in the first place, too. Yeah, some times I happen to try to explain things in terms of "a" and "b" and soon I realize it wasn't effective. What I *think* it would be more effective in first place is *why* people should write apps that one can extend by layering other components on top of it rather than monkey patching or doing all sorts of incantations to achieve what they want. The spelling is important so people can understand how to implement their story (if they know the so called AOP) by using a given package. repoze.plugin just happen to make it easier to associate the concepts of AOP to the code and maybe attract more people. Cool package after all . Fernando ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
On 4/27/09 1:18 PM, Chris McDonough wrote: >> I find the introduction lacking; why do I care about indirection, >> what's the benefit. > > Good point. > > Um. Why *do* we care about indirection? In particular, why do we care about > this sort of generic-function-ish dispatch pattern we call adaptation? Why do > we care about it for *every* application? I'm too brainwashed to answer that > question without thinking about views. If we want something to be bit off by > the larger Python community, we need an answer for this. Answering myself with the kind of navel-gazing which is sure to drive Tres nuts ;-): - We use the heck out of indirections during unit testing. In most of the apps I write personally, the ZCA indirections are the only thing that make it *possible* to write unit tests rather than needing to write functional tests. But typically during testing the idea that some *adapter* is registered against more than one "requires" interface is just something that we deal with rather something that is actively desirable (because we always only have one implementation during unit testing); the actual multidispatch is to support the below case. - We use adaptation and utility indirections in applications to allow people to override implementations without needing to change the code. Most non-Zope people associate this desire to provide pluggability, correctly or incorrectly, with "CMS" systems. But there's something to this conclusion because indeed the ZCA indirections were originally meant to replace use of something like acquisition to find values in "content space". I suspect we are quite brainwashed here, or at least incapable of discounting this use case, because we tend to treat every application as something that might turn into a framework. - We use utility indirections (or at least I do) to retrieve application-specific configuration values (e.g. BFG's ISettings utility, which offers no behavior except as a bag-of-names). I have some ideas about how you might layer several systems together to allow people to only bite off one bit of software for each of these cases. #2 is the most problematic and would be at a higher layer. - C ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Malthe Borch wrote: > 2009/4/27 Tres Seaver : >> I can't see much reason for us to try to share code with people who >> won't even attempt a rational evaluation of the candidate. -1 to >> bikeshedding this thing further; +1 to an 'svn rm'. > > I think the primary reason why people shy away from ``zope.component`` > is that it's abused too often; it's hard to see that it's really quite > simple when some users are multi-adapting four ways to look up a > viewlet which happens to rely on twenty other lookups to render > itself. I think you are being generous: I have very little doubt that the objections come first from the presence of 'zope' in the package name, and second from the very idea of using a tool which codifies and categorizes abstractions, never mind the benefits. > Perhaps if campaigned a bit on the grounds of the relative ease-of-use > of the ZCA, we wouldn't have to dumb it down to the level of > ``repoze.plugin`` (no offense) in order to get adoption outside of > Zope. These are folks who, on the whole, prefer *code generation*, and place and extremely low value on abstraction and "pluggable reuse". I don't think repackaging is going to help the gag reflex. Tres. - -- === Tres Seaver +1 540-429-0999 tsea...@palladion.com Palladion Software "Excellence by Design"http://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFJ9fiA+gerLs4ltQ4RArkdAJ93UdkIupl5Xa52CHb4A+SmxBRAgQCfeoFW 9SG7sADfzbZehsa5KpQkcOk= =xHg2 -END PGP SIGNATURE- ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
On 4/27/09 2:12 PM, Tres Seaver wrote: > -BEGIN PGP SIGNED MESSAGE- > Hash: SHA1 > > Chris McDonough wrote: >> On 4/27/09 1:28 PM, Martin Aspeli wrote: >>> Chris McDonough wrote: >>> But anyway, yeah. For someone who has never used zope.component, though, it's really not that important ("more strictly" compares to zope.component). >>> Reading that page as someone who does use zope.component, I was also not >>> entirely convinced of the rationale for this package. I'm not saying >>> there isn't one (though it smells a bit unfortunate that we're inventing >>> a plugin system that's almost the same as zope.component, yet >>> incompatible), but the aforementioned documentation didn't explain it >>> sufficiently IMHO. >> There's no *good* reason. The only reasons are bad. > > Agreed. > >> The primary driver is that >> we're trying to work with the Pylons community to share implementation bits. >> I >> suggested that they might use something like zope.configuration to do system >> configuration. But it turns out that some in that community are completely >> befuddled by zope.component and those in that community who are not >> befuddled by >> it are actively hostile to it. They may still be befuddled by and hostile to >> something that is simpler, but at least we'll have something to argue about >> on >> technical grounds rather than emotion. > > I can't see much reason for us to try to share code with people who > won't even attempt a rational evaluation of the candidate. Personally, I think there is benefit to both reaching out to people who aren't quite on board as well as participating in some introspection about why we do what we do. I don't attempt a rational evaluation of, say, Mathematica, because I just can't see how it would help me in my every day life. OTOH, if I had a library that just did simple graphing, I'd have some context as to how it might help me (even if I ended up disusing it anyway). > -1 to > bikeshedding this thing further; +1 to an 'svn rm'. Bikeshedding? I'm beggining to hate that word. Like "Pythonic". I really don't care about the bits; it's more a decomposition exercise. There's always your mailer's "ignore thread". - C ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
2009/4/27 Tres Seaver : > I can't see much reason for us to try to share code with people who > won't even attempt a rational evaluation of the candidate. -1 to > bikeshedding this thing further; +1 to an 'svn rm'. I think the primary reason why people shy away from ``zope.component`` is that it's abused too often; it's hard to see that it's really quite simple when some users are multi-adapting four ways to look up a viewlet which happens to rely on twenty other lookups to render itself. Perhaps if campaigned a bit on the grounds of the relative ease-of-use of the ZCA, we wouldn't have to dumb it down to the level of ``repoze.plugin`` (no offense) in order to get adoption outside of Zope. \malthe ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Chris McDonough wrote: > On 4/27/09 1:28 PM, Martin Aspeli wrote: >> Chris McDonough wrote: >> >>> But anyway, yeah. For someone who has never used zope.component, though, >>> it's >>> really not that important ("more strictly" compares to zope.component). >> Reading that page as someone who does use zope.component, I was also not >> entirely convinced of the rationale for this package. I'm not saying >> there isn't one (though it smells a bit unfortunate that we're inventing >> a plugin system that's almost the same as zope.component, yet >> incompatible), but the aforementioned documentation didn't explain it >> sufficiently IMHO. > > There's no *good* reason. The only reasons are bad. Agreed. > The primary driver is that > we're trying to work with the Pylons community to share implementation bits. > I > suggested that they might use something like zope.configuration to do system > configuration. But it turns out that some in that community are completely > befuddled by zope.component and those in that community who are not befuddled > by > it are actively hostile to it. They may still be befuddled by and hostile to > something that is simpler, but at least we'll have something to argue about > on > technical grounds rather than emotion. I can't see much reason for us to try to share code with people who won't even attempt a rational evaluation of the candidate. -1 to bikeshedding this thing further; +1 to an 'svn rm'. Tres. - -- === Tres Seaver +1 540-429-0999 tsea...@palladion.com Palladion Software "Excellence by Design"http://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFJ9fWD+gerLs4ltQ4RAhfEAJ91VMGLi5IaiKqw3+qQzWLEWJ6h/ACg2vMa G4SaaBCNiVrEutkvt2mSVI0= =0dXZ -END PGP SIGNATURE- ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
On 4/27/09 1:28 PM, Martin Aspeli wrote: > Chris McDonough wrote: > >> But anyway, yeah. For someone who has never used zope.component, though, >> it's >> really not that important ("more strictly" compares to zope.component). > > Reading that page as someone who does use zope.component, I was also not > entirely convinced of the rationale for this package. I'm not saying > there isn't one (though it smells a bit unfortunate that we're inventing > a plugin system that's almost the same as zope.component, yet > incompatible), but the aforementioned documentation didn't explain it > sufficiently IMHO. There's no *good* reason. The only reasons are bad. The primary driver is that we're trying to work with the Pylons community to share implementation bits. I suggested that they might use something like zope.configuration to do system configuration. But it turns out that some in that community are completely befuddled by zope.component and those in that community who are not befuddled by it are actively hostile to it. They may still be befuddled by and hostile to something that is simpler, but at least we'll have something to argue about on technical grounds rather than emotion. - C ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
On Apr 27, 2009, at 1:18 PM, Chris McDonough wrote: > On 4/27/09 5:19 AM, Malthe Borch wrote: >> I realize this documentation[1] is still in progress; yet, here are >> some comments, posted to the list to maybe encourage some kind of >> debate (since it's likely that there will be several consumers of >> this >> package in repoze.* in the future: >> >> I find the introduction lacking; why do I care about indirection, >> what's the benefit. > > Good point. > > Um. Why *do* we care about indirection? In particular, why do we > care about > this sort of generic-function-ish dispatch pattern we call > adaptation? Why do > we care about it for *every* application? I'm too brainwashed to > answer that > question without thinking about views. If we want something to be > bit off by > the larger Python community, we need an answer for this. > >> Next, I can't read through the documentation if it's going to be all >> "a" and "somecomponent"; can we have some kind of context, e.g. a >> story-line or some likely scenario. This would help a lot in >> motivating the package in the first place, too. > > Yep. > >> >> >> Instead, components (such as “adapters” and “utilities”) are >> registered using marker “component types” >> >> >> This is a cool feature and it should probably be mentioned upfront >> (e.g. not in the last section of the documentation); because >> afterall, >> you can program more strictly by adapting to marker-objects. > > I'm actually having a bit of trouble naming those things. At first > they were > called "plugin types", then "provides types", then finally > "component types". > None of those names really work for me. Why not just markers? or in the spirit of plugs, prongs > > But anyway, yeah. For someone who has never used zope.component, > though, it's > really not that important ("more strictly" compares to > zope.component). > > - C > ___ > Repoze-dev mailing list > Repoze-dev@lists.repoze.org > http://lists.repoze.org/listinfo/repoze-dev ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
Chris McDonough wrote: > But anyway, yeah. For someone who has never used zope.component, though, > it's > really not that important ("more strictly" compares to zope.component). Reading that page as someone who does use zope.component, I was also not entirely convinced of the rationale for this package. I'm not saying there isn't one (though it smells a bit unfortunate that we're inventing a plugin system that's almost the same as zope.component, yet incompatible), but the aforementioned documentation didn't explain it sufficiently IMHO. Martin -- Author of `Professional Plone Development`, a book for developers who want to work with Plone. See http://martinaspeli.net/plone-book ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] repoze.plugin documentation
On 4/27/09 5:19 AM, Malthe Borch wrote: > I realize this documentation[1] is still in progress; yet, here are > some comments, posted to the list to maybe encourage some kind of > debate (since it's likely that there will be several consumers of this > package in repoze.* in the future: > > I find the introduction lacking; why do I care about indirection, > what's the benefit. Good point. Um. Why *do* we care about indirection? In particular, why do we care about this sort of generic-function-ish dispatch pattern we call adaptation? Why do we care about it for *every* application? I'm too brainwashed to answer that question without thinking about views. If we want something to be bit off by the larger Python community, we need an answer for this. > Next, I can't read through the documentation if it's going to be all > "a" and "somecomponent"; can we have some kind of context, e.g. a > story-line or some likely scenario. This would help a lot in > motivating the package in the first place, too. Yep. > > >Instead, components (such as “adapters” and “utilities”) are > registered using marker “component types” > > > This is a cool feature and it should probably be mentioned upfront > (e.g. not in the last section of the documentation); because afterall, > you can program more strictly by adapting to marker-objects. I'm actually having a bit of trouble naming those things. At first they were called "plugin types", then "provides types", then finally "component types". None of those names really work for me. But anyway, yeah. For someone who has never used zope.component, though, it's really not that important ("more strictly" compares to zope.component). - C ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev