[Zope3-dev] Packaging conventions (was Re: PyCon DC 2003: Call For Papers)

Phillip J. Eby pje@telecommunity.com
Sun, 15 Dec 2002 13:40:10 -0500


Before delving any further into details, let me just clarify that my 
position on "api" or "public" modules was not advocating that Zope should 
use them.  I am +.5 on them, in the sense that I'm comfortable with the 
approach from my own projects, and it addresses certain issues regarding 
separability of components.  I'm -1 on anything that makes it hard to reuse 
pieces of Zope 3 packages.

That having been said...


At 03:30 PM 12/14/02 -0500, Jim Fulton wrote:
>Phillip J. Eby wrote:
>>At 04:28 PM 12/13/02 -0500, Jim Fulton wrote:
>>
>>>Phillip J. Eby wrote:
>>>..
>>>
>>>>from peak.naming import api as naming
>>>
>>>
>>>And this is good ... why?
>>
>>1. Everything in the naming API is then only one dot away
>>2. Access is via a prefix ("naming.") so the top-level namespace in the 
>>importing module isn't cluttered or conflicting.
>
>You don't need an api module for this. You could just:
>
>   from peak import naming

Right, except then the __init__ issues come into play.


>>>What is the advantage of api over __init__?
>>
>>Makes it possible for packages which want to reuse part of a package, not 
>>to require the whole thing to be imported.  This can slash the startup 
>>and runtimes for small scripts enormously (in proportion to the script's 
>>total run time).
>
>But then these can't import api either, as api would have the same
>effect.

That's correct.  When a mutual dependency exists between two packages, they 
have to import from each other directly, bypassing the API.


>I would say that __init__ should only expose things that are really
>always wanted. A package could have other modules, useful in some cases
>that aren't exposed by init.
>
>>There are also some advantages to simplifying import order for 
>>interdependent packages; For example, if you have a package A whose 
>>classes want to provide an interface from package B, but package B 
>>contains things that depend on A's classes.  Being able to say:
>>A:
>>from B.interfaces import ISomething
>>B:
>>from B.somemodule import Something
>>Without having to sort out a precise ordering in the package __init__ 
>>modules can be a nice convenience.
>
>I'm confused. Neither of the above import api.  I also don't
>follow the second example.

Argh.  I typoed.  that second line should have been "from A.somemodule 
import Something".

Anyway, as I said above, mutually dependent packages have to bypass the API 
module.  The point is, they *can* bypass it.  If __init__ is the API 
module, they can't.