A common issue we are seeing is that we have eggs depending on each other, but they still need to load the zcml from those dependencies somehow. As a temporary solution to play with the concept I added something simple to the plone.recipe.zope2instance buildout recipe. It allows you to define entrypoints like this: entry_points={ "zope.zcml" : [ "meta = plone.session", "configure = plone.session", ], }, this tells the system to load meta.zcml and configure.zcml from plone.session. I am not quite sure what the best way to hook this into Zope itself is. For Zope 2 we can do it in Five, since that is where all the zcml loading logic currently is. Or we could move that into Zope2 itself somewhere. I'm not familiar enough with Zope3 to know what the best place would be there. One problem is ordering: the zope.component zcml needs to be loaded first. Perhaps we need to build an egg dependency graph and walk through that to load zcml entry points in the right order. As long as all dependencies are registered correctly that should work. Wichert. -- Wichert Akkerman <wichert@wiggy.net> It is simple to make things. http://www.wiggy.net/ It is hard to make things simple.
On 10/17/07, Wichert Akkerman <wichert@wiggy.net> wrote:
A common issue we are seeing is that we have eggs depending on each other, but they still need to load the zcml from those dependencies somehow. As a temporary solution to play with the concept I added something simple to the plone.recipe.zope2instance buildout recipe.
What's the problem you're seeing? I'm not sure what you're trying to solve. ZCML includes work just fine in the egg world. As long as you're referring to packaged ZCML using package="package.name" in your <include> and <includeOverrides> directives, all is good. -Fred -- Fred L. Drake, Jr. <fdrake at gmail.com> "Chaos is the score upon which reality is written." --Henry Miller
Fred Drake wrote:
On 10/17/07, Wichert Akkerman <wichert@wiggy.net> wrote:
A common issue we are seeing is that we have eggs depending on each other, but they still need to load the zcml from those dependencies somehow. As a temporary solution to play with the concept I added something simple to the plone.recipe.zope2instance buildout recipe.
What's the problem you're seeing? I'm not sure what you're trying to solve. ZCML includes work just fine in the egg world.
As long as you're referring to packaged ZCML using package="package.name" in your <include> and <includeOverrides> directives, all is good.
The main win, IMHO, is to avoid the requirement for people to install slugs for third party products. Slugs suck - they are confusing to explain and people forget them all the time. Buildout makes it a bit easier, but it's still not a terribly good solution. For example, say you want to install oi.plum. You need to add the line 'oi.plum' twice - once under 'eggs' and once under 'zcml' in your buildout.cfg. Forget the latter, and the package doesn't work properly (or at all). If we had entry points, we could just load the egg. Internally, oi.plum may use <include /> as much as necessary to load *its* dependencies, but that's not something the user of the package needs to worry about. If Zope loaded entry-point ZCML automatically (maybe with an on/off switch in zope.conf for those who need more fine grained control) that'd be a pretty nice solution. Martin -- Author of `Professional Plone Development`, a book for developers who want to work with Plone. See http://martinaspeli.net/plone-book
On 10/17/07, Martin Aspeli <optilude@gmx.net> wrote:
The main win, IMHO, is to avoid the requirement for people to install slugs for third party products. Slugs suck - they are confusing to explain and people forget them all the time. Buildout makes it a bit easier, but it's still not a terribly good solution.
Slugs are evil; agreed. We never use them. They were an accident of the "instance" tree inherited from older versions of Zope, and how that tree was re-interpreted for Zope 3. They never worked well, and did no one any favors.
For example, say you want to install oi.plum. You need to add the line 'oi.plum' twice - once under 'eggs' and once under 'zcml' in your buildout.cfg. Forget the latter, and the package doesn't work properly (or at all).
I actually really like this; I don't get the configuration for a package unless I ask for it. It's not unusual to want only the code and not the default configuration for a package.
If we had entry points, we could just load the egg. Internally, oi.plum may use <include /> as much as necessary to load *its* dependencies, but that's not something the user of the package needs to worry about.
Requiring a package doesn't say anything about how it's going to be used; making an assumption about that is really bad.
If Zope loaded entry-point ZCML automatically (maybe with an on/off switch in zope.conf for those who need more fine grained control) that'd be a pretty nice solution.
I suspect I'd always want it off. Picking up configuration willy-nilly is too dangerous. -Fred -- Fred L. Drake, Jr. <fdrake at gmail.com> "Chaos is the score upon which reality is written." --Henry Miller
Fred Drake wrote:
On 10/17/07, Martin Aspeli <optilude@gmx.net> wrote:
The main win, IMHO, is to avoid the requirement for people to install slugs for third party products. Slugs suck - they are confusing to explain and people forget them all the time. Buildout makes it a bit easier, but it's still not a terribly good solution.
Slugs are evil; agreed. We never use them. They were an accident of the "instance" tree inherited from older versions of Zope, and how that tree was re-interpreted for Zope 3. They never worked well, and did no one any favors.
Glad we all agree.
For example, say you want to install oi.plum. You need to add the line 'oi.plum' twice - once under 'eggs' and once under 'zcml' in your buildout.cfg. Forget the latter, and the package doesn't work properly (or at all).
I actually really like this; I don't get the configuration for a package unless I ask for it. It's not unusual to want only the code and not the default configuration for a package.
Right - but you're building an application, and you're pretty experienced with Zope. A lot of Plone users just want to install a plug-in (a product), basically. Before, they just dropped it into a directory. Now, they declare it twice in a file (presuming there's a cheese shop release). That's a (small) step backwards (duplication). Declaring it once would be a step forwards (no manual download)
If we had entry points, we could just load the egg. Internally, oi.plum may use <include /> as much as necessary to load *its* dependencies, but that's not something the user of the package needs to worry about.
Requiring a package doesn't say anything about how it's going to be used; making an assumption about that is really bad.
Maybe. I agree there should be an option not to do this, and many eggs may choose *not* to use an entry point. For things like Plone add-on products, though, it makes much more sense to have it be automatic. To generalise further - if what you're installing is a high level, cohesive product, with a UI and an install method and all the rest of it, having installation be as simple as possible is a big win. For the components further down the stack (e.g. the things that these high level products are depending on!), having the processing be explicit (via <include /> directives) makes more sense.
If Zope loaded entry-point ZCML automatically (maybe with an on/off switch in zope.conf for those who need more fine grained control) that'd be a pretty nice solution.
I suspect I'd always want it off. Picking up configuration willy-nilly is too dangerous.
Maybe it's off by default, then, but I *know* this would make the add-on products story in Plone easier: I've seen people struggle with slugs, editing site.zcml is far tto scary, and you don't always have a package that you own to include other things from. I suspect entry points would make life simpler for other systems that used a similar mechanism for plug-ins/add-ons. However, I agree that they're not appropriate for more fundamental libraries. Martin -- Author of `Professional Plone Development`, a book for developers who want to work with Plone. See http://martinaspeli.net/plone-book
Martin Aspeli <optilude@gmx.net> writes:
Fred Drake wrote:
On 10/17/07, Martin Aspeli <optilude@gmx.net> wrote:
The main win, IMHO, is to avoid the requirement for people to install slugs for third party products. Slugs suck - they are confusing to explain and people forget them all the time. Buildout makes it a bit easier, but it's still not a terribly good solution.
Slugs are evil; agreed. We never use them. They were an accident of the "instance" tree inherited from older versions of Zope, and how that tree was re-interpreted for Zope 3. They never worked well, and did no one any favors.
Glad we all agree.
For example, say you want to install oi.plum. You need to add the line 'oi.plum' twice - once under 'eggs' and once under 'zcml' in your buildout.cfg. Forget the latter, and the package doesn't work properly (or at all).
I actually really like this; I don't get the configuration for a package unless I ask for it. It's not unusual to want only the code and not the default configuration for a package.
Right - but you're building an application, and you're pretty experienced with Zope. A lot of Plone users just want to install a plug-in (a product), basically. Before, they just dropped it into a directory. Now, they declare it twice in a file (presuming there's a cheese shop release). That's a (small) step backwards (duplication). Declaring it once would be a step forwards (no manual download)
If we had entry points, we could just load the egg. Internally, oi.plum may use <include /> as much as necessary to load *its* dependencies, but that's not something the user of the package needs to worry about.
Requiring a package doesn't say anything about how it's going to be used; making an assumption about that is really bad.
Maybe. I agree there should be an option not to do this, and many eggs may choose *not* to use an entry point. For things like Plone add-on products, though, it makes much more sense to have it be automatic. To generalise further - if what you're installing is a high level, cohesive product, with a UI and an install method and all the rest of it, having installation be as simple as possible is a big win. For the components further down the stack (e.g. the things that these high level products are depending on!), having the processing be explicit (via <include /> directives) makes more sense.
If Zope loaded entry-point ZCML automatically (maybe with an on/off switch in zope.conf for those who need more fine grained control) that'd be a pretty nice solution.
I suspect I'd always want it off. Picking up configuration willy-nilly is too dangerous.
Maybe it's off by default, then, but I *know* this would make the add-on products story in Plone easier: I've seen people struggle with slugs, editing site.zcml is far tto scary, and you don't always have a package that you own to include other things from.
I suspect entry points would make life simpler for other systems that used a similar mechanism for plug-ins/add-ons. However, I agree that they're not appropriate for more fundamental libraries.
I'm new to eggs, but maybe both sides could be satisfied with an approach like extra_requires? You could list "oi.plum [zope.zcml]" when you require oi.plum *and* its ZCML and then it's ZCML would get loaded. Is this easily possible with eggs and/or buildout? If not, maybe it's a worthwhile extension. I guess the abstracted idea would be some way to pass configuration directives to eggs as a part of requiring them. Ross
On Oct 17, 2007, at 8:04 PM, Ross Patterson wrote: ...
I'm new to eggs, but maybe both sides could be satisfied with an approach like extra_requires?
Extras are evil. See other posts of mine for explanations of why.
You could list "oi.plum [zope.zcml]" when you require oi.plum *and* its ZCML and then it's ZCML would get loaded. Is this easily possible with eggs and/or buildout?
easy_install has nothing to do with loading ZCML. A recipe could do something, but extra-requires don't help in any useful way. Jim -- Jim Fulton Zope Corporation
On 10/17/07, Martin Aspeli <optilude@gmx.net> wrote:
Right - but you're building an application, and you're pretty experienced with Zope. A lot of Plone users just want to install a plug-in (a product), basically. Before, they just dropped it into a
It sounds like your concerns center around users of a pluggable/extensible application (like Plone), rather than being general Zope concerns. It's certainly reasonable for an application to want a plugin architecture that works that way. Perhaps the development teams for the applications would be interested in getting together and sharing a package that supports a plugin architecture that works that way. That would be a good place to share effort without negatively impacting users who need bare-metal Zope or the developers of applications that don't have similar plugin-management requirements. -Fred -- Fred L. Drake, Jr. <fdrake at gmail.com> "Chaos is the score upon which reality is written." --Henry Miller
Fred Drake wrote:
On 10/17/07, Martin Aspeli <optilude@gmx.net> wrote:
Right - but you're building an application, and you're pretty experienced with Zope. A lot of Plone users just want to install a plug-in (a product), basically. Before, they just dropped it into a
It sounds like your concerns center around users of a pluggable/extensible application (like Plone), rather than being general Zope concerns. It's certainly reasonable for an application to want a plugin architecture that works that way.
I'd say it is a general concern of a framework to try to avoid how often you need to repeat yourself. Right now you to use a Zope 3 package you need to do the following things: * list the egg in your setup.py dependencies * load the ZCML required * import it in your code Investigating ways to reduce this sounds like a win from a framework perspective. Getting rid of the separate ZCML step would help as it'd make it more similar to just reusing an arbitrary Python package, making Zope less special in some ways.
Perhaps the development teams for the applications would be interested in getting together and sharing a package that supports a plugin architecture that works that way. That would be a good place to share effort without negatively impacting users who need bare-metal Zope or the developers of applications that don't have similar plugin-management requirements.
Sure, we should always avoid negatively impacting people who want to repeat themselves in many places as they need the control in some places. :) That's a given constraint with the bare Zope 3 libraries we'll need to keep in mind always. The ability to not use this should be present, and I'm fine if the default is not to use this. Systems like Plone and Grok can always turn this on. Regards, Martijn
On 10/20/07, Martijn Faassen <faassen@startifact.com> wrote:
I'd say it is a general concern of a framework to try to avoid how often you need to repeat yourself. Right now you to use a Zope 3 package you need to do the following things:
* list the egg in your setup.py dependencies
* load the ZCML required
* import it in your code
True. But they do different things. 1. Says "download and install a component" 2. Says "configure a component" 3. Says "use a component" Or something like that. I must say I kinda prefer the method of including the ZCML from the application zcml, where it is used, than having it magically included by buildout just because it was downloaded and installed. This mainly because if I write a module that requires foo.bar.frotz to have it's zcml included, I think it's the job of my module to include it, not a separate buildout. But I see your point as well, and maybe there could be made a difference in the buildout between modules to just be installed and modules to be installed and configured? -- Lennart Regebro: Zope and Plone consulting. http://www.colliberty.com/ +33 661 58 14 64
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Lennart Regebro wrote:
On 10/20/07, Martijn Faassen <faassen@startifact.com> wrote:
I'd say it is a general concern of a framework to try to avoid how often you need to repeat yourself. Right now you to use a Zope 3 package you need to do the following things:
* list the egg in your setup.py dependencies
* load the ZCML required
* import it in your code
True. But they do different things.
1. Says "download and install a component" 2. Says "configure a component" 3. Says "use a component"
Or something like that.
I must say I kinda prefer the method of including the ZCML from the application zcml, where it is used, than having it magically included by buildout just because it was downloaded and installed. This mainly because if I write a module that requires foo.bar.frotz to have it's zcml included, I think it's the job of my module to include it, not a separate buildout.
But I see your point as well, and maybe there could be made a difference in the buildout between modules to just be installed and modules to be installed and configured?
I'd rather see eggs designed to be used as plugins for a pluggable app (e.g., Plone / Zope2 Products, maybe Grok add-ons) expose and entry point in their setup.py, which would then be found and triggered automagically by the plugin-aware application. E.g., a stock Zope2 product, bundled as an egg, might expose the following in its setup() call:: entry_points={ 'zope2.product': ['Products.myproduct:initialize'[, }, Or maybe the product even exposes mroe than one kind of entry point:: entry_points={ 'zope2.product': ['Products.myproduct:initialize'], 'plone.quickinstall': ['Products.myproduct.Extensions.Install:install'], }, A Grok application might say: entry_points={ 'grok.module': ['myapp'], }, The entry points feature of setuptools was originall added in order to support this use case (plugins / add-ons for a particular framework). Tres. - -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@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 iD8DBQFHGjXJ+gerLs4ltQ4RAjsPAJ9XUPLazljd5m5GmJarLoLURXpAygCgpw31 7pBQ1xtoHbFY0H/EAJ7KJVE= =ytRr -----END PGP SIGNATURE-----
Hey, On 10/20/07, Lennart Regebro <regebro@gmail.com> wrote:
On 10/20/07, Martijn Faassen <faassen@startifact.com> wrote:
I'd say it is a general concern of a framework to try to avoid how often you need to repeat yourself. Right now you to use a Zope 3 package you need to do the following things:
* list the egg in your setup.py dependencies
* load the ZCML required
* import it in your code
True. But they do different things.
1. Says "download and install a component" 2. Says "configure a component" 3. Says "use a component"
Sure, they do different things. Nonetheless, there is repetition that could be reduced. In fact there's potentially a fourth place now where we reference dependency information again: 4. Use this version of this component (though this may be maintained outside of the actual package) In at least 3 places we express dependency information. For different *purposes* in each case, but we still state something like: 1. "we use dependency X, and please download and install it" 2. "we use dependency X, please configure it" 3. "we use dependency X, please import the following from it" It'd be nice if I only had to say "I want to import from dependency X, please make sure it's there and available." Actually this is a little bit like zc.resourcelibrary can make resources appear on your page headers when you write code that needs it. Of course this is sometimes not possible, as there's not enough information available, or there are multiple separate ways to configure it. But there is significant repetition spread out across the codebase. It's not in one place, which forces a repetition in referring to the component being installed/configured/imported. My response is to think about ways to reduce this (while of course, looking for ways to retain power and flexibility). Regards, Martijn
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Martijn Faassen wrote:
Hey,
On 10/20/07, Lennart Regebro <regebro@gmail.com> wrote:
On 10/20/07, Martijn Faassen <faassen@startifact.com> wrote:
I'd say it is a general concern of a framework to try to avoid how often you need to repeat yourself. Right now you to use a Zope 3 package you need to do the following things:
* list the egg in your setup.py dependencies
* load the ZCML required
* import it in your code True. But they do different things.
1. Says "download and install a component" 2. Says "configure a component" 3. Says "use a component"
Sure, they do different things. Nonetheless, there is repetition that could be reduced. In fact there's potentially a fourth place now where we reference dependency information again:
4. Use this version of this component
(though this may be maintained outside of the actual package)
In at least 3 places we express dependency information. For different *purposes* in each case, but we still state something like:
1. "we use dependency X, and please download and install it" 2. "we use dependency X, please configure it" 3. "we use dependency X, please import the following from it"
It'd be nice if I only had to say "I want to import from dependency X, please make sure it's there and available."
setuptools spells that semantic so:
import pkg_resources loaded = require('zope.interface 3.4.0')
At that point, the 'zope.interface' egg is guaranteed to be on sys.path, and with the desired version: the subsequent:
import zope.interface
will then come from that location. This presumes that you haven't already hacked sys.path to include it from somewhere else ('requires' appends entries there). Note that if 'grok' itself explicitly pins all its requirements (the "frozen egg" scenario), then just saying:
pkg_resources.require('grok')
would have the effect of loading *all* the pinned requirements eggs onto sys.path.
Actually this is a little bit like zc.resourcelibrary can make resources appear on your page headers when you write code that needs it.
Of course this is sometimes not possible, as there's not enough information available, or there are multiple separate ways to configure it.
But there is significant repetition spread out across the codebase. It's not in one place, which forces a repetition in referring to the component being installed/configured/imported. My response is to think about ways to reduce this (while of course, looking for ways to retain power and flexibility).
If you expose an 'entry point group" for the automagic ZCML loader to use, then you don't require any repetition in the client code, because the plugin provide conforms to a standard interface which allows discovery:: # Assume that plugins register one or more entry points for the group, # 'plone.automatic_zcml', where each entry point is a module name whose # ZCML is to be loaded.
from zope.configuration.xmlconfig import xmlconfig for ep in pkg_resources.iter_entry_points('plone.automatic_zcml'): ... module_name = ep.module_name ... # trigger ZCML loading here using 'module_name' ... stream = pkg_resources.resource_stream(module_name, ... 'configure.zcml') ... xmlconfig(stream)
[1] http://peak.telecommunity.com/DevCenter/setuptools#dynamic-discovery-of-serv... [2] http://peak.telecommunity.com/DevCenter/PythonEggs#accessing-package-resourc... Tres. - -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@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 iD8DBQFHHMDB+gerLs4ltQ4RAsGRAKCqpHz3HJjzlscWDAlrXnygKXlNIwCffSsn aumELzdGgsHQoZDDPSPoTSw= =GHqp -----END PGP SIGNATURE-----
On 10/22/07, Martijn Faassen <faassen@startifact.com> wrote:
In at least 3 places we express dependency information. For different *purposes* in each case, but we still state something like:
1. "we use dependency X, and please download and install it" 2. "we use dependency X, please configure it" 3. "we use dependency X, please import the following from it"
It'd be nice if I only had to say "I want to import from dependency X, please make sure it's there and available." Actually this is a little bit like zc.resourcelibrary can make resources appear on your page headers when you write code that needs it.
Of course this is sometimes not possible, as there's not enough information available, or there are multiple separate ways to configure it.
In the end I guess this all is just more arguments for separating the functions and the views into separate eggs. -- Lennart Regebro: Zope and Plone consulting. http://www.colliberty.com/ +33 661 58 14 64
On Oct 22, 2007, at 11:46 AM, Lennart Regebro wrote:
On 10/22/07, Martijn Faassen <faassen@startifact.com> wrote:
In at least 3 places we express dependency information. For different *purposes* in each case, but we still state something like:
1. "we use dependency X, and please download and install it" 2. "we use dependency X, please configure it" 3. "we use dependency X, please import the following from it"
It'd be nice if I only had to say "I want to import from dependency X, please make sure it's there and available." Actually this is a little bit like zc.resourcelibrary can make resources appear on your page headers when you write code that needs it.
Of course this is sometimes not possible, as there's not enough information available, or there are multiple separate ways to configure it.
In the end I guess this all is just more arguments for separating the functions and the views into separate eggs.
I think maybe more abstractly, it might be useful to think about separating based on libraries vs. applications. Libraries should be as policy-free as possible (otherwise they're not libraries, they're applications). Applications, however, must declare policies (or they would be useless, this is what makes them applications [sorry for the reflexive tautology]), but this makes them not useful outside of some context. If a library egg contains an entry point that either loaded or returned a stream for the moral equivalent of meta.zcml, that would be fine. But it would be less OK for an egg which represented a library's ZCML to contain adapter and utlity registrations. However, if the egg represented an application, it would be fine for it to do either. Zope 2 'Products' are usually applications in a sense, because they are *never* useful outside the context of Zope-the-application- server, and that's why Five's automagical load of "meta", "configure", and "overrides" ZCML is completely appropriate for them, and why it would make sense, if products became eggs, to have all of their ZCML loaded at Zope startup time. However, the presence of some ZCML in a non-Product library doesn't mean that its ZCML should be loaded, IMO. Zope-3-the-application uses site.zcml to selectively load configurations, and I think that's about the right policy. We could devise some way of spelling the equivalent of site.zcml as an entry point for eggs-that-are-applications, and as any "include package" directives in that zcml should "just work", there probably shouldn't be any additional machinery within zcml itself to cause other ZCML to be loaded from multiple packages via some omnibus search pattern. We don't really complain too badly right now that setuptools doesn't infer all of our dependencies for us from import statements in the packages it contains in order to prevent us from having to manually specify dependencies in our setup.py. This is because even though it probably could (py2exe does something like this), it's more trouble than it's worth in because the import statements themselves don't contain enough information (version, location, is it an absolute requirement or a nice-to-have?) if you want to treat the dependencies as independently release-managed entities. That said, if you just want to "freeze" some configuration up, it would become reasonable to treat some sandbox as a fully-configured set of things that should get packaged up as a glob and shipped off, but this is the opposite of what we want to do with eggs in the long term, I think. - C
Hello, On 10/24/07, Chris McDonough <chrism@plope.com> wrote: [snip]
I think maybe more abstractly, it might be useful to think about separating based on libraries vs. applications. Libraries should be as policy-free as possible (otherwise they're not libraries, they're applications). Applications, however, must declare policies (or they would be useless, this is what makes them applications [sorry for the reflexive tautology]), but this makes them not useful outside of some context. If a library egg contains an entry point that either loaded or returned a stream for the moral equivalent of meta.zcml, that would be fine. But it would be less OK for an egg which represented a library's ZCML to contain adapter and utlity registrations. However, if the egg represented an application, it would be fine for it to do either.
I am not sure I see such a hard distinction between applications and libraries myself, at least not on the boundary of adapter and utility registrations. I think in many cases libraries provide default implementations of adapters, for instance, and default global utility registrations. This makes the library more easy to use without having to do extra work, if at least the defaults apply to your work. You may of course have to override the default behavior, by registering an adapter for a more specific interface or class, or by registering a local utility. Take a library that registers views (multi adapters) as widgets for form fields, for instance. Do you consider this to be an application-like library? I consider this to be a library.
Zope 2 'Products' are usually applications in a sense, because they are *never* useful outside the context of Zope-the-application- server, and that's why Five's automagical load of "meta", "configure", and "overrides" ZCML is completely appropriate for them, and why it would make sense, if products became eggs, to have all of their ZCML loaded at Zope startup time.
I can see where you're coming from, but you are stretching the terminology to its breaking point, though. I really don't consider XMLWidgets or ParsedXML to be *applications*. I don't even consider Formulator to be one. We have to look at their intent. Their intent is to provide components that can be reused to create applications. If anything, that mean they're libraries (that provide components). They're libraries highly coupled to Zope 2, of course. Zope 2 isn't designed with loosely coupled libraries in mind. It's not great. But to go calling these 'applications' I think might cause a lot of confusion in terminology. I'd like us to come up with better words to describe heavily-coupled versus loosely-coupled, and policy-heavy versus policy-light or policy-free. [snip]
We don't really complain too badly right now that setuptools doesn't infer all of our dependencies for us from import statements in the packages it contains in order to prevent us from having to manually specify dependencies in our setup.py.
We might not, but this one has been in the back of my mind for a while. I'd like to be able to write code where I just import something, and poof, it's there. Of course such automation can be dangerous, but hopefully it could be tamed. With Zope we add a third structure to it: ZCML dependencies, and while two places may be an accident, three places definitely calls for some thinking about don't repeat yourself. Again, I see your points. I think it makes sense for libraries to be light on policy. It's also clear that for instance ZMI views are too much policy one gets with a typical Zope 3 library. I don't think we should however consider all libraries that register a few adapters as 'policy heavy'. Once we take the ZMI registrations out, is what is left policy-heavy or policy-light? Regards, Martijn
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Martijn Faassen wrote:
Hello,
On 10/24/07, Chris McDonough <chrism@plope.com> wrote: [snip]
I think maybe more abstractly, it might be useful to think about separating based on libraries vs. applications. Libraries should be as policy-free as possible (otherwise they're not libraries, they're applications). Applications, however, must declare policies (or they would be useless, this is what makes them applications [sorry for the reflexive tautology]), but this makes them not useful outside of some context. If a library egg contains an entry point that either loaded or returned a stream for the moral equivalent of meta.zcml, that would be fine. But it would be less OK for an egg which represented a library's ZCML to contain adapter and utlity registrations. However, if the egg represented an application, it would be fine for it to do either.
I am not sure I see such a hard distinction between applications and libraries myself, at least not on the boundary of adapter and utility registrations. I think in many cases libraries provide default implementations of adapters, for instance, and default global utility registrations. This makes the library more easy to use without having to do extra work, if at least the defaults apply to your work. You may of course have to override the default behavior, by registering an adapter for a more specific interface or class, or by registering a local utility.
Take a library that registers views (multi adapters) as widgets for form fields, for instance. Do you consider this to be an application-like library? I consider this to be a library.
I can see that. I still don't want its view registrations automagically included in my configuration. If it exposes an entry point signalling that it is a plugin for the specific application I'm running, that would be different.
Zope 2 'Products' are usually applications in a sense, because they are *never* useful outside the context of Zope-the-application- server, and that's why Five's automagical load of "meta", "configure", and "overrides" ZCML is completely appropriate for them, and why it would make sense, if products became eggs, to have all of their ZCML loaded at Zope startup time.
Maybe we need to add a term, 'plugin', to describe things like Zope2 products which register only "behavior" and not "addable applications." The line gets fuzzy here, too: PAS uses 'plugin' to describe an object which is added to a persistent user folder, and then configured to perform one or more roles in its framework. Oooh, there's another term, 'framework'. In my mind, 'frameworks' declare interfaces for 'plugins' to supply. OTOH, 'frameworks' don't want every possible plugin to be magicdally configured: they are all about explicit configuration. Plone makes configuring QuickInstaller-enabled products explicit: the site manager gets to choose at runtime (not at startup), and can change her mind later. In that sense, Plone is 'framework'-like, rather than 'application'-like.
I can see where you're coming from, but you are stretching the terminology to its breaking point, though. I really don't consider XMLWidgets or ParsedXML to be *applications*. I don't even consider Formulator to be one. We have to look at their intent. Their intent is to provide components that can be reused to create applications. If anything, that mean they're libraries (that provide components). They're libraries highly coupled to Zope 2, of course. Zope 2 isn't designed with loosely coupled libraries in mind. It's not great. But to go calling these 'applications' I think might cause a lot of confusion in terminology. I'd like us to come up with better words to describe heavily-coupled versus loosely-coupled, and policy-heavy versus policy-light or policy-free.
[snip]
We don't really complain too badly right now that setuptools doesn't infer all of our dependencies for us from import statements in the packages it contains in order to prevent us from having to manually specify dependencies in our setup.py.
We might not, but this one has been in the back of my mind for a while. I'd like to be able to write code where I just import something, and poof, it's there. Of course such automation can be dangerous, but hopefully it could be tamed. With Zope we add a third structure to it: ZCML dependencies, and while two places may be an accident, three places definitely calls for some thinking about don't repeat yourself.
The 'pkg_resources.require' function lets you spell your dependency before you import; you'd still have to import whatever names you wanted from the distribution, but you could be naming both in the same module.
Again, I see your points. I think it makes sense for libraries to be light on policy. It's also clear that for instance ZMI views are too much policy one gets with a typical Zope 3 library. I don't think we should however consider all libraries that register a few adapters as 'policy heavy'. Once we take the ZMI registrations out, is what is left policy-heavy or policy-light?
I don't want to have to override *any* policy imposed by a library, unless I specifically choose to enable that policy in the first place. Tres. - -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@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 iD8DBQFHH1/s+gerLs4ltQ4RAgt6AKCBcNbbVuL+uAsE/14ObFGFlKcIIQCeOZb9 hUXK73WjzcnHekVR7iGnKMU= =Lz7n -----END PGP SIGNATURE-----
Hey, On 10/24/07, Tres Seaver <tseaver@palladion.com> wrote:
Martijn Faassen wrote: [snip]
Take a library that registers views (multi adapters) as widgets for form fields, for instance. Do you consider this to be an application-like library? I consider this to be a library.
I can see that. I still don't want its view registrations automagically included in my configuration. If it exposes an entry point signalling that it is a plugin for the specific application I'm running, that would be different.
I propose below to classify these entry points not by application but by type. You'll almost have to otherwise you'll end up touching quite a few libraries for each framework or pluggable application that gets written, right?
The 'pkg_resources.require' function lets you spell your dependency before you import; you'd still have to import whatever names you wanted from the distribution, but you could be naming both in the same module.
Right, I did read what you pointed out elsewhere in this discussion. Thanks for pointing that out. It bears some investigation. I am wondering whether we can make some buildout recipe that, together with a database of what distributions provide which imports, can determine what to fetch and bake it into the setup.py of the package under development. Together with a 'known good versions' system it could even fetch a reasonable version.
Again, I see your points. I think it makes sense for libraries to be light on policy. It's also clear that for instance ZMI views are too much policy one gets with a typical Zope 3 library. I don't think we should however consider all libraries that register a few adapters as 'policy heavy'. Once we take the ZMI registrations out, is what is left policy-heavy or policy-light?
I don't want to have to override *any* policy imposed by a library, unless I specifically choose to enable that policy in the first place.
Sure, but one person's policy is another person's behavior. :) I disagree with the position that should not ever treat an adapter registration as an implementation detail to provide some default behavior. Sometimes the behavior of a library *relies* on certain adapters being registered. An example is an adapter registration to generate an appropriate error message (if no more specific adapters are registered by the user of the library). Anyway, I think we're mostly going round and round. Currently we're debating what the entry point means that says "load the basic ZCML". So perhaps we need a "minimum ZCML" and "convenient defaults ZCML" entry point, which may be one and the same in some cases. A framework can then choose to load convenient defaults by default, or absolute minimum stuff by default. To get started we should pick one entry point - if someone finds it loads too much policy we can add another one, or if someone finds it loads too little, likewise. Regards, Martijn
Martijn Faassen wrote at 2007-10-24 18:38 +0200:
... I disagree with the position that should not ever treat an adapter registration as an implementation detail to provide some default behavior. Sometimes the behavior of a library *relies* on certain adapters being registered. An example is an adapter registration to generate an appropriate error message (if no more specific adapters are registered by the user of the library).
But requiring that a more specific adapter must be registered can be a bit tedious -- as it may require to define an additional (and unnatural) interface that derives from the original one -- just to be able to register a more specific adapter... -- Dieter
On 10/24/07, Tres Seaver <tseaver@palladion.com> wrote:
Maybe we need to add a term, 'plugin', to describe things like Zope2 products which register only "behavior" and not "addable applications." The line gets fuzzy here, too: PAS uses 'plugin' to describe an object which is added to a persistent user folder, and then configured to perform one or more roles in its framework. Oooh, there's another term, 'framework'. In my mind, 'frameworks' declare interfaces for 'plugins' to supply. OTOH, 'frameworks' don't want every possible plugin to be magicdally configured: they are all about explicit configuration.
It gets fuzzy, but I think trying to get a common usage of the words is useful. And your usage seems useful. Note that of course PAS is both a plugin *and* a framework in this usage. :-)
Plone makes configuring QuickInstaller-enabled products explicit: the site manager gets to choose at runtime (not at startup), and can change her mind later. In that sense, Plone is 'framework'-like, rather than 'application'-like.
I can definitely see a use in the zope3 and grok world for some more ZODB persistent configuration. Maybe much of what is today actually done in ZCML shuld rather be done there? -- Lennart Regebro: Zope and Plone consulting. http://www.colliberty.com/ +33 661 58 14 64
On Oct 24, 2007, at 12:54 PM, Lennart Regebro wrote:
On 10/24/07, Tres Seaver <tseaver@palladion.com> wrote:
Maybe we need to add a term, 'plugin', to describe things like Zope2 products which register only "behavior" and not "addable applications." The line gets fuzzy here, too: PAS uses 'plugin' to describe an object which is added to a persistent user folder, and then configured to perform one or more roles in its framework. Oooh, there's another term, 'framework'. In my mind, 'frameworks' declare interfaces for 'plugins' to supply. OTOH, 'frameworks' don't want every possible plugin to be magicdally configured: they are all about explicit configuration.
It gets fuzzy, but I think trying to get a common usage of the words is useful. And your usage seems useful.
Note that of course PAS is both a plugin *and* a framework in this usage. :-)
Plone makes configuring QuickInstaller-enabled products explicit: the site manager gets to choose at runtime (not at startup), and can change her mind later. In that sense, Plone is 'framework'-like, rather than 'application'-like.
I can definitely see a use in the zope3 and grok world for some more ZODB persistent configuration. Maybe much of what is today actually done in ZCML shuld rather be done there?
Does it need to be persistent or just placeful? Being able to specify multiple component registries via ZCML (maybe within a container tag), and then associating one with a 'site' has always seemed to make sense to me. - C
On 10/25/07, Chris McDonough <chrism@plope.com> wrote:
I can definitely see a use in the zope3 and grok world for some more ZODB persistent configuration. Maybe much of what is today actually done in ZCML shuld rather be done there?
Does it need to be persistent or just placeful?
I'd want it to be persistent, but I can't say it "needs" to be. :-) Something GenericSetup-like to configure which components should be configured would be nice. -- Lennart Regebro: Zope and Plone consulting. http://www.colliberty.com/ +33 661 58 14 64
Hi all,
Betreff: Re: [Zope-dev] Re: [Plone-developers] zcml entry points
On 10/25/07, Chris McDonough <chrism@plope.com> wrote:
I can definitely see a use in the zope3 and grok world for some more ZODB persistent configuration. Maybe much of what is today actually done in ZCML shuld rather be done there?
Does it need to be persistent or just placeful?
I'd want it to be persistent, but I can't say it "needs" to be. :-) Something GenericSetup-like to configure which components should be configured would be nice.
Just a side note Take a look at z3c.baseregistry, there is a great pattern. If something has to be in a registry for a site, you can use a basregsitry and give the site this additional registry. This means a baseregistry is a global registry, persistent assigned to a local site. Baseregistries can be assigned to one or more local sites. Such a baseregistry could contain a full grock or plone setup, all done in zcml and only assigned to one specific local site. The baseregistry concept was developed for heavy customizing of different instances sharing the same codebase including configure.zcml Regards Roger Ineichen
-- Lennart Regebro: Zope and Plone consulting. http://www.colliberty.com/ +33 661 58 14 64 _______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )
Martijn Faassen wrote at 2007-10-20 03:15 +0200:
... I'd say it is a general concern of a framework to try to avoid how often you need to repeat yourself. Right now you to use a Zope 3 package you need to do the following things:
* list the egg in your setup.py dependencies
* load the ZCML required
* import it in your code
Investigating ways to reduce this sounds like a win from a framework perspective. Getting rid of the separate ZCML step would help as it'd make it more similar to just reusing an arbitrary Python package, making Zope less special in some ways.
Zope 2 had (for products) all three things together. It was felt that this was a too tight coupling. Therefore, for Zope 3 the paradigma "explicit is better than implicit" (a paradigma, that I personally dislike and find wrong) was used. Now, you want again more things to happen implicitly. In my view, this is natural -- but not in the Zope 3 spirit... -- Dieter
Hey, On 10/20/07, Dieter Maurer <dieter@handshake.de> wrote: [snip]
Zope 2 had (for products) all three things together.
It was felt that this was a too tight coupling. Therefore, for Zope 3 the paradigma "explicit is better than implicit" (a paradigma, that I personally dislike and find wrong) was used.
Now, you want again more things to happen implicitly. In my view, this is natural -- but not in the Zope 3 spirit...
Sure, but while I fully acknowledge problems with the Zope 2 approach, in my view we've gone a bit overboard at times with the Zope 3 spirit. :) There is value in thinking about compact expression. The great benefit with Zope 3 is that we frequently actually *know* the aspects of what we want to express compactly, as we tend to be expressing these aspects separately. I hope we can foster a spirit where after we have factored out the independent aspects we can look at them again and make their expression more compact, at least for whatever we determine is a common case. Regards, Martijn
Hey, Martin Aspeli wrote:
Fred Drake wrote: [snip]
For example, say you want to install oi.plum. You need to add the line 'oi.plum' twice - once under 'eggs' and once under 'zcml' in your buildout.cfg. Forget the latter, and the package doesn't work properly (or at all).
I actually really like this; I don't get the configuration for a package unless I ask for it. It's not unusual to want only the code and not the default configuration for a package.
Right - but you're building an application, and you're pretty experienced with Zope. A lot of Plone users just want to install a plug-in (a product), basically. Before, they just dropped it into a directory. Now, they declare it twice in a file (presuming there's a cheese shop release). That's a (small) step backwards (duplication). Declaring it once would be a step forwards (no manual download)
Right - if I understand this well, this would introduce the option not to have to repeat yourself. You use the egg and that takes care of loading the ZCML. Sounds like a good thing, as long as it can somehow be turned off. This would be a good thing for Grok to have. Regards, Martijn
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Martijn Faassen wrote:
Hey,
Martin Aspeli wrote:
Fred Drake wrote: [snip]
For example, say you want to install oi.plum. You need to add the line 'oi.plum' twice - once under 'eggs' and once under 'zcml' in your buildout.cfg. Forget the latter, and the package doesn't work properly (or at all). I actually really like this; I don't get the configuration for a package unless I ask for it. It's not unusual to want only the code and not the default configuration for a package. Right - but you're building an application, and you're pretty experienced with Zope. A lot of Plone users just want to install a plug-in (a product), basically. Before, they just dropped it into a directory. Now, they declare it twice in a file (presuming there's a cheese shop release). That's a (small) step backwards (duplication). Declaring it once would be a step forwards (no manual download)
Right - if I understand this well, this would introduce the option not to have to repeat yourself. You use the egg and that takes care of loading the ZCML. Sounds like a good thing, as long as it can somehow be turned off. This would be a good thing for Grok to have.
Unless the authors of the eggs you are using have exactly your use cases, automagically enabling all the ZCML in their pacakge is going to cause you grief. In this case, as in classic Zope3, convenience and clean reuse are pulling in separate directions. With all its warts, at least the QuickInstaller tool in Plone allows the site manager to choose which plugins to enable / disable. Now, if the Grok admin UI kept a persistent list of the enbled packages, and exposed a way to inspect both the available and enbaled versions, that would be a reasonable facility. The Zope2 Control_Panel could expose a similar feature for "product"-like packages. Tres. - -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@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 iD8DBQFHGVx6+gerLs4ltQ4RAqbJAKCI2vSgdTJdmr8zl/0jCE+29GI7XACfTJyD s0ihiC+PyRkx0P0emWGd1PU= =71qa -----END PGP SIGNATURE-----
Martin Aspeli wrote:
Fred Drake wrote:
On 10/17/07, Wichert Akkerman <wichert@wiggy.net> wrote:
A common issue we are seeing is that we have eggs depending on each other, but they still need to load the zcml from those dependencies somehow. As a temporary solution to play with the concept I added something simple to the plone.recipe.zope2instance buildout recipe.
What's the problem you're seeing? I'm not sure what you're trying to solve. ZCML includes work just fine in the egg world.
As long as you're referring to packaged ZCML using package="package.name" in your <include> and <includeOverrides> directives, all is good.
The main win, IMHO, is to avoid the requirement for people to install slugs for third party products. Slugs suck - they are confusing to explain and people forget them all the time. Buildout makes it a bit easier, but it's still not a terribly good solution.
For example, say you want to install oi.plum. You need to add the line 'oi.plum' twice - once under 'eggs' and once under 'zcml' in your buildout.cfg. Forget the latter, and the package doesn't work properly (or at all).
I see a different win. At the moment we are declaring dependencies in two places: in the egg information and in the zcml files. For every package I need I need to make sure its zcml is loaded, which means I need to have a meta.zcml, configure.zcml and overrides.zcml which load the meta, configure and overrides from all packages I depend on. I also need to inspect every package I depend on to check if they have a meta, configure or overrides.zcml, which in my humble opinion should be just an implementation detail that I, as someone who is just using the zope stack/framework, should not need to know about. Multiply that with the number of dependencies you see in zope.* and you see this becomes very unwieldy. So I turned things around: if I state in my egg information that I require another package that means I need to have that package available and functional. Which suggests that its zcml has to be loaded before mine. And that is exactly what I am doing: adding an entry point that allows a package to say "in order to function I need to have these zcml files loaded". Wichert. -- Wichert Akkerman <wichert@wiggy.net> It is simple to make things. http://www.wiggy.net/ It is hard to make things simple.
Martin Aspeli wrote:
Fred Drake wrote:
On 10/17/07, Wichert Akkerman <wichert@wiggy.net> wrote:
A common issue we are seeing is that we have eggs depending on each other, but they still need to load the zcml from those dependencies somehow. As a temporary solution to play with the concept I added something simple to the plone.recipe.zope2instance buildout recipe.
What's the problem you're seeing? I'm not sure what you're trying to solve. ZCML includes work just fine in the egg world.
As long as you're referring to packaged ZCML using package="package.name" in your <include> and <includeOverrides> directives, all is good.
The main win, IMHO, is to avoid the requirement for people to install slugs for third party products. Slugs suck - they are confusing to explain and people forget them all the time. Buildout makes it a bit easier, but it's still not a terribly good solution.
For example, say you want to install oi.plum. You need to add the line 'oi.plum' twice - once under 'eggs' and once under 'zcml' in your buildout.cfg. Forget the latter, and the package doesn't work properly (or at all).
I see a different win. At the moment we are declaring dependencies in two places: in the egg information and in the zcml files. For every package I need I need to make sure its zcml is loaded, which means I need to have a meta.zcml, configure.zcml and overrides.zcml which load the meta, configure and overrides from all packages I depend on. I also need to inspect every package I depend on to check if they have a meta, configure or overrides.zcml, which in my humble opinion should be just an implementation detail that I, as someone who is just using the zope stack/framework, should not need to know about. Multiply that with the number of dependencies you see in zope.* and you see this becomes very unwieldy. So I turned things around: if I state in my egg information that I require another package that means I need to have that package available and functional. Which suggests that its zcml has to be loaded before mine. And that is exactly what I am doing: adding an entry point that allows a package to say "in order to function I need to have these zcml files loaded". Wichert. -- Wichert Akkerman <wichert@wiggy.net> It is simple to make things. http://www.wiggy.net/ It is hard to make things simple.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Wichert Akkerman wrote:
Martin Aspeli wrote:
Fred Drake wrote:
On 10/17/07, Wichert Akkerman <wichert@wiggy.net> wrote:
A common issue we are seeing is that we have eggs depending on each other, but they still need to load the zcml from those dependencies somehow. As a temporary solution to play with the concept I added something simple to the plone.recipe.zope2instance buildout recipe.
What's the problem you're seeing? I'm not sure what you're trying to solve. ZCML includes work just fine in the egg world.
As long as you're referring to packaged ZCML using package="package.name" in your <include> and <includeOverrides> directives, all is good.
The main win, IMHO, is to avoid the requirement for people to install slugs for third party products. Slugs suck - they are confusing to explain and people forget them all the time. Buildout makes it a bit easier, but it's still not a terribly good solution.
For example, say you want to install oi.plum. You need to add the line 'oi.plum' twice - once under 'eggs' and once under 'zcml' in your buildout.cfg. Forget the latter, and the package doesn't work properly (or at all).
I see a different win. At the moment we are declaring dependencies in two places: in the egg information and in the zcml files. For every package I need I need to make sure its zcml is loaded, which means I need to have a meta.zcml, configure.zcml and overrides.zcml which load the meta, configure and overrides from all packages I depend on. I also need to inspect every package I depend on to check if they have a meta, configure or overrides.zcml, which in my humble opinion should be just an implementation detail that I, as someone who is just using the zope stack/framework, should not need to know about. Multiply that with the number of dependencies you see in zope.* and you see this becomes very unwieldy.
So I turned things around: if I state in my egg information that I require another package that means I need to have that package available and functional. Which suggests that its zcml has to be loaded before mine. And that is exactly what I am doing: adding an entry point that allows a package to say "in order to function I need to have these zcml files loaded".
I may not *want* the other package's ZCML to be loaded: some of its policies may not be appropriate for my application. I think that the "library" vs. "pluggable application" distinction is valid here: maybe you want to define an entry point in the egg which a given pluggable app would use at startup time to configure all the plugins which exposed that entry point. Five fakes such an entry point now by implicitly loading meta.zcml, then configure.zcml, then overrides.zcml for all packages it recognizes as products: are you proposing to replace Five's DWIM with a new, explicit version? Tres. - -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@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 iD4DBQFHF07w+gerLs4ltQ4RApigAJQKD7QktS+kRjxD3XiJ76p/QEjXAKCuhpNk oKng4r5TQOJiuL9WFZst0A== =91pF -----END PGP SIGNATURE-----
Tres Seaver wrote:
I may not *want* the other package's ZCML to be loaded: some of its policies may not be appropriate for my application. I think that the "library" vs. "pluggable application" distinction is valid here: maybe you want to define an entry point in the egg which a given pluggable app would use at startup time to configure all the plugins which exposed that entry point.
+1
Five fakes such an entry point now by implicitly loading meta.zcml, then configure.zcml, then overrides.zcml for all packages it recognizes as products: are you proposing to replace Five's DWIM with a new, explicit version?
That may be preferable, but quite hard from a BBB perspective. Right now all kinds of products exist that just expect their ZCML to be automagically loaded. Martin -- Author of `Professional Plone Development`, a book for developers who want to work with Plone. See http://martinaspeli.net/plone-book
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Martin Aspeli wrote:
Tres Seaver wrote:
I may not *want* the other package's ZCML to be loaded: some of its policies may not be appropriate for my application. I think that the "library" vs. "pluggable application" distinction is valid here: maybe you want to define an entry point in the egg which a given pluggable app would use at startup time to configure all the plugins which exposed that entry point.
+1
Five fakes such an entry point now by implicitly loading meta.zcml, then configure.zcml, then overrides.zcml for all packages it recognizes as products: are you proposing to replace Five's DWIM with a new, explicit version?
That may be preferable, but quite hard from a BBB perspective. Right now all kinds of products exist that just expect their ZCML to be automagically loaded.
I'm not arguing against preserving the majyk done for things Zope2 calls 'Products'; however, I don't want to extend the majyk any further. I would also be fine with adding a new directive which caused explicit triggering of introspected ZCML, e.g.: <!-- Load ZCML from all packages which register a 'meta.zcml' entry point --> <majyk entry_point="meta.zcml" /> <!-- Load ZCML from all packages which register a 'configure.zcml' entry point --> <majyk entry_point="configure.zcml" /> I *really* don't see the point, by the way, in automagically running 'overrides.zcml' from products: by definition, the reusable package author doesn't know enough to override declarations made by other reusable packages. If a site manager wants to configure overides, then adding them manually to her site.zcml should be fine. Tres. - -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@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 iD8DBQFHF5mM+gerLs4ltQ4RAu1+AJ0RtIXJaedfzgEXbL+5cjYDNJI+rQCfRCtY 9DqQBllKGsr7wMAjVW6WQWA= =Yl5B -----END PGP SIGNATURE-----
On Oct 18, 2007, at 8:17 AM, Tres Seaver wrote:
I may not *want* the other package's ZCML to be loaded: some of its policies may not be appropriate for my application. I think that the "library" vs. "pluggable application" distinction is valid here: maybe you want to define an entry point in the egg which a given pluggable app would use at startup time to configure all the plugins which exposed that entry point.
This probably an indication that there are two (I know, that horrible number) types of packages: - packages which provide zcml sugar in the form of new directive definitions - packages which perform component registrations It seems that packages which do only the former could be classified as a "true" library while the latter is more application-y. It seems like in a perfect world, libraries should not need any configure.zcml, just a meta.zcml which contains little except meta directives. Personally I think it would be more useful to remove policy-laden registrations from existing packages so they're more libraryish and move these registrations into "site.zcml" (or an entry point moral equivalent) than it would be to attempt to annoint the status quo as the right thing by implementing dependency graph traversal. - C
Tres Seaver wrote:
Wichert Akkerman wrote: [snip]
So I turned things around: if I state in my egg information that I require another package that means I need to have that package available and functional. Which suggests that its zcml has to be loaded before mine. And that is exactly what I am doing: adding an entry point that allows a package to say "in order to function I need to have these zcml files loaded".
I may not *want* the other package's ZCML to be loaded: some of its policies may not be appropriate for my application.
Since this appears to be a rare case that is the exception, what about using the new ZCML exclude framework for this case? You need to know what you are doing, but this use case is for people who know exactly what they're doing anyway, right? Regards, Martijn
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Martijn Faassen wrote:
Tres Seaver wrote:
Wichert Akkerman wrote: [snip]
So I turned things around: if I state in my egg information that I require another package that means I need to have that package available and functional. Which suggests that its zcml has to be loaded before mine. And that is exactly what I am doing: adding an entry point that allows a package to say "in order to function I need to have these zcml files loaded". I may not *want* the other package's ZCML to be loaded: some of its policies may not be appropriate for my application.
Since this appears to be a rare case that is the exception, what about using the new ZCML exclude framework for this case? You need to know what you are doing, but this use case is for people who know exactly what they're doing anyway, right?
It isn't that rare: how many people want to turn off the Rotterdam skin in Z3, for instance? In general, the authors of a "library" package can't anticipate how their code will be used; the ZCML they provide is intended to cover the cases they know or imagine most people want. ZCML represents policy, not mechanism, and hence is inherently less reusable than code. Tres. - -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@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 iD8DBQFHGV1F+gerLs4ltQ4RAjRaAKCuDy247kYNF5Ol6T6lHl0EQWprCwCgmOoX eKcm7W1oh739digDWK0SG5g= =1y7d -----END PGP SIGNATURE-----
Tres Seaver wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Martijn Faassen wrote:
Tres Seaver wrote:
Wichert Akkerman wrote: [snip]
So I turned things around: if I state in my egg information that I require another package that means I need to have that package available and functional. Which suggests that its zcml has to be loaded before mine. And that is exactly what I am doing: adding an entry point that allows a package to say "in order to function I need to have these zcml files loaded". I may not *want* the other package's ZCML to be loaded: some of its policies may not be appropriate for my application. Since this appears to be a rare case that is the exception, what about using the new ZCML exclude framework for this case? You need to know what you are doing, but this use case is for people who know exactly what they're doing anyway, right?
It isn't that rare: how many people want to turn off the Rotterdam skin in Z3, for instance? In general, the authors of a "library" package can't anticipate how their code will be used; the ZCML they provide is intended to cover the cases they know or imagine most people want.
That probably depends a bit on how that package is created though. In an ideal world, Rotterdam would be a separate package (or packages) that could be pulled in or not (i.e. if you don't depend on it and/or you don't include its ZCML file and/or you use the zc.configure exclude behaviour to turn it off).
ZCML represents policy, not mechanism, and hence is inherently less reusable than code.
That is true, but how many people actually re-do all the ZCML for all the packages they use? Most packages, I imagine, will have been built with re-use in mind. They make appropriate use of adapters and marker interfaces and whatever else so that the user of the package has some control, or even an opt-out. But for most packages, I don't think there's going to be a host of different policies that are actually interesting. Put differently, in Plone we choose not to include various packages, but the ones we *do* use, we tend to use wholesale. We may override (or use a more-specific adapter for) some policy decisions, e.g. when it was written for zope 3 and we need some zope 2 magic, but up until now that's tended to be pretty manageable. I fully subscribe to the separation of policy and implementation (though I think in practice, "policy" is often something you override with specific adapters or utilities, not only expressed in ZCML), but I really hope that most Zope 3 developers don't end up reading, understanding and may reproducing every single line of ZCML in every single package they ever depend on. :) I think Jim's suggestion was good, though: Something like Plone or Grok - that want to be "pluggable applications" - could use an <includeEntryPoints /> type ZCML directive to process ZCML pulled in via entry points. Other packages may choose not to do that. Other packages again, may choose to do that but then use zc.configure to turn some stuff off, or just override whatever registrations they need. Martin -- Author of `Professional Plone Development`, a book for developers who want to work with Plone. See http://martinaspeli.net/plone-book
Hey, On 10/20/07, Tres Seaver <tseaver@palladion.com> wrote:
Martijn Faassen wrote: [snip]
Since this appears to be a rare case that is the exception, what about using the new ZCML exclude framework for this case? You need to know what you are doing, but this use case is for people who know exactly what they're doing anyway, right?
It isn't that rare: how many people want to turn off the Rotterdam skin in Z3, for instance? In general, the authors of a "library" package can't anticipate how their code will be used; the ZCML they provide is intended to cover the cases they know or imagine most people want.
ZCML represents policy, not mechanism, and hence is inherently less reusable than code.
I'd be nice if alternate policies could be expressed in the dependency structure itself then. This might imply that commonly-used policy ZCML should be in its own package altogether. With automatic loading, you'd get this as soon as you install the package. If the policy is very particular to a particular application and has no reuse potential at all, it has no business being in our repository anyway (except as part of this application, of course). Regards, Martijn
On Friday 19 October 2007 21:17, Martijn Faassen wrote:
Tres Seaver wrote:
I may not *want* the other package's ZCML to be loaded: some of its policies may not be appropriate for my application.
+1. Happens to me all the time.
Since this appears to be a rare case that is the exception, what about using the new ZCML exclude framework for this case? You need to know what you are doing, but this use case is for people who know exactly what they're doing anyway, right?
-1. Regards, Stephan -- Stephan Richter CBU Physics & Chemistry (B.S.) / Tufts Physics (Ph.D. student) Web2k - Web Software Design, Development and Training
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Wichert Akkerman wrote:
A common issue we are seeing is that we have eggs depending on each other, but they still need to load the zcml from those dependencies somehow. As a temporary solution to play with the concept I added something simple to the plone.recipe.zope2instance buildout recipe.
It allows you to define entrypoints like this:
entry_points={ "zope.zcml" : [ "meta = plone.session", "configure = plone.session", ], },
this tells the system to load meta.zcml and configure.zcml from plone.session.
I am not quite sure what the best way to hook this into Zope itself is. For Zope 2 we can do it in Five, since that is where all the zcml loading logic currently is. Or we could move that into Zope2 itself somewhere. I'm not familiar enough with Zope3 to know what the best place would be there.
One problem is ordering: the zope.component zcml needs to be loaded first.
That's a packaging bug: any package whose ZCML won't load without having zope.component loaded already needs to add the explicit inclusion (duplicates do *not* conflict for the <include> directive).
Perhaps we need to build an egg dependency graph and walk through that to load zcml entry points in the right order. As long as all dependencies are registered correctly that should work.
I'd rather fix the ZCML files. Tres. - -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@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 iD8DBQFHFstL+gerLs4ltQ4RAnE+AKCeuEvcOW9P9BKMXJ0lJE5dxRtorwCfXgXO Md2MbCD/PGIClJ/cvmJPeE4= =Ti55 -----END PGP SIGNATURE-----
On Oct 17, 2007, at 4:44 PM, Wichert Akkerman wrote:
A common issue we are seeing is that we have eggs depending on each other, but they still need to load the zcml from those dependencies somehow. As a temporary solution to play with the concept I added something simple to the plone.recipe.zope2instance buildout recipe.
It allows you to define entrypoints like this:
entry_points={ "zope.zcml" : [ "meta = plone.session", "configure = plone.session", ], },
this tells the system to load meta.zcml and configure.zcml from plone.session.
Sure, where presumably you could list multiple files. Or maybe: entry_points = """ [zcml] meta = <include package="plone.session" /> configure = <include package="plone.session" /> """ ... entry_points=entry_points (This example uses the ConfigParser syntax for specifying entry points, which I prefer.) This suggestion gives you the flexibility to specify ZCML to be included by package name, by file name, or both. It lets you specify other ZCML as well.
entry_points={ "zope.zcml" : [ "meta = plone.session", "configure = plone.session", ], },
I am not quite sure what the best way to hook this into Zope itself is. For Zope 2 we can do it in Five, since that is where all the zcml loading logic currently is. Or we could move that into Zope2 itself somewhere. I'm not familiar enough with Zope3 to know what the best place would be there.
I recommend creating new configuration directives that do this. <include meta_entry_points /> <include entry_points /> These directives might also accept an projects attribute to name specific eggs, by project name, to load from. This could be used in Zope 2 and in Zope 3 apps that want it. (Mine wouldn't. :) Doing it this way keeps it simple to use while providing some added flexibility to do explicit configuration before or after this automatic configuration.
One problem is ordering: the zope.component zcml needs to be loaded first.
As Tres noted, a package that needs zope.component to be included should include it. In general, I recommend that a package include all of the ZCML it expects to be included. I understand that some folks would fine something like this to be very useful. I can especially see the benefit for pluggable apps, like Plone and Zope 2.. I support this idea. I would almost certainly not use it myself and can't justify my time to implement this. I think the implementation is pretty straightforward though and encourage folks who want this to implement it. It can be implemented as a separate package, although I wouldn't object to eventually incorporating it into zope.configuration. Jim -- Jim Fulton Zope Corporation
Hi. I can also see potential uses for this. Hopefully the utility will implemented as a zpl package so that it may eventually make it into zope.configuration. Many thanks. Regards, David Jim Fulton wrote:
I understand that some folks would fine something like this to be very useful. I can especially see the benefit for pluggable apps, like Plone and Zope 2.. I support this idea. I would almost certainly not use it myself and can't justify my time to implement this. I think the implementation is pretty straightforward though and encourage folks who want this to implement it. It can be implemented as a separate package, although I wouldn't object to eventually incorporating it into zope.configuration.
Jim
-- Jim Fulton Zope Corporation
_______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists -http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )
participants (13)
-
Chris McDonough -
David Pratt -
Dieter Maurer -
Fred Drake -
Jim Fulton -
Lennart Regebro -
Martijn Faassen -
Martin Aspeli -
Roger Ineichen -
Ross Patterson -
Stephan Richter -
Tres Seaver -
Wichert Akkerman