[Zope3-dev] Importing

Martijn Faassen faassen@vet.uu.nl
Wed, 12 Dec 2001 15:12:20 +0100


Guido van Rossum wrote:
> > > Ah, the relative import fallacy.  Why is it required to be able to
> > > reparent a package without changing the source?  
> > 
> > So that a package may be re-used as a sub-package in another package without
> > having to re-write or otherwise fudge all the import statements in the import
> > package.
> 
> I don't find that an important requirement.

Use case:

I want to place my unit tests in a sub package in my main package. Let's
imagine my package is called NodePath and let's imagine it's a sub package
of ParsedXML, which is a Zope product. It has a 'tests' subpackage containing
the unit tests.

In order to write the unit tests, I need to be able to import the NodePath code
in the package above it. The NodePath code has been written so that it can
(hopefully) be used with DOM implementations other than the one in ParsedXML.
Thus, I'd not want the 'tests' sub package to be dependent on ParsedXML.
Right now I do have to either do an explicit import at the top of my
unit tests: 

  from Products.ParsedXML import NodePath

Or I have to use ugly hackery:

  import sys
  sys.path.insert(0, "../..")

  import NodePath

If I use the former I'll have to introduce a dependency on ParsedXML in
the unit tests that didn't need to be there before. Of course if you look
at the CVS archives of ParsedXML you'd notice I was fudging here, as I 
did introduce a dependency on ParsedXML in the unit tests (I needed to call
its parser to parse XML into a DOM tree). I don't think this is a valid
objection however; I could've used a general framework for retrieving a
DOM parser from somewhere instead, perhaps even using a placeful 
approach.

It seems rather frustrating that while my NodePath package has no dependency on 
ParsedXML at all, in order to use its unit tests I do need to introduce
such a dependency (or to do sys.path hackery). 

Perhaps a better way to solve it is to place the NodePath package somewhere
on the Python path directly instead of as a sub package of ParsedXML.
This would make distribution a lot harder however; instead of just installing
a single ParsedXML package in lib/python/Products a user now has to
install the NodePath package in lib/python and the ParsedXML package
in lib/python/Products. While I foresee an independent future of NodePath
eventually I don't want to make users have to do that just yet.

Regards,

Martijn