[Product-Developers] Re: unit test on Plone 4.0b1

Derek Broughton derek at pointerstop.ca
Sun Mar 21 15:37:30 UTC 2010

Martin Aspeli wrote:

> Derek Broughton wrote:
>> Martin Aspeli wrote:
>>> I think the rule of thumb is pretty easy:
>>>    - if you import from a package in your own code, declare a dependency
>>> on it
>>> So, if you use 'from Products.CMFCore.utils import getToolByName', then
>>> declare a dependency on 'Products.CMFCore'. If that package disappeared
>>> from the dependency tree, your code would break.
>> That just sounds to me to be another reason why I should never use
>> getToolByName.
> I don't think this has anything to do with the thread. It was just an
> example. 

I think it's a fine example.  I'm just trying to get at "best practices" 

> What if you imported IContentish? Or anything else from any
> other package.

That's the whole point though: "anything" is too broad, "nothing" is too 
lax.  It seems to me that it should be correct to define a dependency on 
Plone and get everything I need to do basic Plone actions.  That should 
include Products.CMFCore, and yes, I think it should include "IContentish".  
Should it include Archetypes?  I would think so, but maybe that is going too 
far.  Certainly, if Plone stops using Archetype contents (and it seems to be 
going that way), I would like to be confronted with the decision whether to 
migrate my own content or to explicitly depend on AT.  If I blindly add AT 
as a dependency, my product will use it long after everybody else stops.

> Any direct dependency should be declared. You can get away without doing
> it, but that exposes you to more risk of breakage in the future. 

And I maintain that breakage is far better than pulling in a long-
deprecated, no-longer-maintained dependency.  Probably there comes a point 
when you plan to retire maintenance of your own product that you _should_ 
declare every last dependency, but to do so when you're in active 
development seems likely to cause more problems than it solves.  
Particularly with this major upgrade to Plone 4, I want to see all of my 
products break, rather than pulling in Plone 3-only dependencies.  If my 
Plone instances are polluted by non-Plone 4 software, it had better be 
somebody else's fault :-)

>> I'm afraid I still don't understand why
>> "getToolByName(context, 'portal_catalog')" is more correct than
>> "context.portal_catalog".
> For one thing, it's a lot easier to understand for anyone reading your
> code.

I think that's highly debatable.  

> The fact that you're acquiring that tool from the portal root is just a
> (pretty stupid) implementation detail. What you're really doing is
> asking the framework to give you a handle on the catalog so you can use
> it. When (not if) tools stop being acquirable like this, you'll get no
> sympathy for having to change your code. ;)

I'm not expecting any (I use acquisition here only for one-off scripts, or 
digging in Clouseau).  I just still don't understand why acquisition of 
tools has come to be seen as a bad idea.  I understand moving from Tools to 
Utilities, but I don't understand why that rules out still making them 
acquirable.  Acquisition is one of the most powerful (if difficult to 
understand) parts of Zope, and it's a shame to throw it away.  And I don't 
happen to see it as a "pretty stupid" implementation detail - it's classic 
OOP and elegant.

More information about the Product-Developers mailing list