[Zope3-dev] Importing

Guido van Rossum guido@python.org
Wed, 12 Dec 2001 23:02:01 -0500


> Lalo Martins wrote:
> > Sorry, I have to agree with Guido. If you don't want NodePath to be
> > dependent on ParsedXML, then it shouldn't be a subpackage. Install it
> > (in a Zope2 environment) in lib/python or even lib/python/Shared/Faassen.
> 
> But NodePath isn't dependent on ParsedXML right now. Only its unit
> tests are. I could keep NodePath completely independent of things
> just fine. If I have package A with subpackage B, and B has a subpackage C,
> why does C have to be dependent on A while B does not? C is only
> dependent on B, after all.
> 
> And why do I have to make people install 2 packages, one of which isn't
> in Products, when previously I only had to distribute one? Don't we want
> to avoid having to install product code outside of lib/python/Products?
> Perhaps Zope Page Templates can get away with it, but I'd certainly get
> wary if I had to install a non-ZC package that way. Not to mention
> wondering at the presumption of the product author!
> 
> I'm writing modular code and life is being made harder for me because of
> it. I could've just avoided the problem by placing the unit tests along
> with the NodePath code, but the Zope guidelines expect a tests
> subdir. Do I have to distribute two packages instead of one because I follow
> the Zope unit testing guidelines?
> 
> Perhaps this isn't a Python problem but a Zope products distribution 
> problem. But it's a problem people occasionally run into, obviously,
> and perhaps Zope3 can make life easier in this respect. Or do you
> and Guido reject these problems out of hand as non-issues? Granted
> they're not world shattering difficulties. :)

I don't call it a non-issue, but I think you want something that is
actually not good for you.  Consider the situation you sketch above,
where you have a package A that you wrote and which needs a package B
that you didn't wrote (or that's simply independent of it).  You can
distribute them together in a tar file, with an install script that
installs each in its proper place -- using distutils that's actually
very easy.  Or you can place them both in a parent package C that only
exists as a convenient container for the two packages you distribute.
The latter *seems* easier for you, and that's why you're asking me to
make it easier for you (by allowing multi-level relative imports).
But if you have several packages A1, A2, A3 that you distribute
independently and that all need the same B, you end up not only
distributing but also *installing* several copies of B, as subpackages
of C1, C2, C3 (the container packages).  Each copy of B has its own
global state, causing memory bloat in Python if A1...An are used
together, and that state cannot be shared (suppose B maintains some
kind of cache -- then C1.B, C2.B and C3.B each maintain their own
cache).

If there's ever other software that needs to use B, it either needs to
figure out in which container package B lives -- or distribute its own
copy of B.

Sure, there are situations where version issues require you to
distribute your own copy of B -- then I suggest that as a professional
software developer and distributor you won't have a problem with doing
a global substitute on the import statements to rename all references
to B to C.B.

Note that Java doesn't have relative import at all.  There, you pick a
unique package name and stick with it, and repeat it in every import.
I'd like us to do the same for Python -- remembering explicit is
better than implicit" in Tim's Zen of Python.  Distutils and
site-packages have enough flexibility to support this.  For example,
you can install all your packages in a subdirectory of site-packages
that doesn't have an __init__.py, and use a .pth file to automatically
add this directory to sys.path.

--Guido van Rossum (home page: http://www.python.org/~guido/)