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

Martin Aspeli optilude+lists at gmail.com
Sun Mar 21 14:17:39 UTC 2010

Derek Broughton wrote:
> Martin Aspeli wrote:
>> Ross Patterson wrote:
>>> Derek Broughton<derek at pointerstop.ca>   writes:
>>>> Wichert Akkerman wrote:
>>>>> On 3/20/10 15:33 , Derek Broughton wrote:
>>>>>> Thanks for this discussion - I'm loathe to even test Plone4 at the
>>>>>> moment beccause I don't know enough about this sort of change.
>>>>>> Surely, though, dependencies on something like CMFCore should be
>>>>>> fulfilled by declaring the dependency on Plone.
>>>>> They are, but you should never rely on that: Plone might be modified
>>>>> to not use CMFCore anymore itself, and your package would suddenly
>>>>> break.  For Plone and CMFCore that is not very likely short term, but
>>>>> in general you should never rely on indirect dependencies. They
>>>>> *will* hurt you at some point.
>>>> Ah, but I rather look at it the opposite way - I _should_ rely on
>>>> indirect dependencies for something like CMFCore, because I only use
>>>> it as required in Plone.  If plone was to drop that dependency and use
>>>> something else (specifically this _did_ happen with CMFCore
>>>> Permissions - at least the module moved), I _want_ my product to break
>>>> and require me to fix my code.  The absolutely last thing I want is
>>>> for my code to continue to import something that will only be used by
>>>> my own products while everybody else is doing something different.
>>> +1  Well said, I've often thought this when I've heard the
>>> above install_requires dogma.
>> 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. What if you imported IContentish? Or anything else from any 
other package.

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. If 
you're experienced enough to make calculations about the risk of 
breakage vs. the time you save by not adding a line to setup.py, go 
ahead and make the judgment. But if you're not, follow the rule of thumb 

> 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.

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. ;)

Also, it provides some safety (for certain known tools, at least) 
against clashing names in the acquisition chain.


Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

More information about the Product-Developers mailing list