So, a bit of a problem came up with pip and namespace packages.  Here's my understanding of what's going on:

When you install a namespace package with pip, it uses install --single-version-externally-managed, and generally the namespace directory is empty and there's a *.nspkg.pth file that has this:

import sys,new,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('<NAMESPACE>',)); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('zope',new.module('zope')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p)

So the lack of an __init__.py file doesn't really matter, because it's created right there, and has its __path__ added to.  But there's a problem when there's another namespace package elsewhere on the path, that wasn't installed with pip (or Setuptools) and uses pkgutils.extend_path(__path__, __name__).  This doesn't get imported because of that .pth file, and the .pth file doesn't itself use extend_path, so the path isn't searched.  This is currently happening with Zope packages installed with plain distutils, then another package installed with the zope namespace elsewhere with pip.  (When using easy_install, I think pkg_resource.declare_namespace comes into play somewhere, and this seems to handle this case, but I'm not sure why the installation is different with pip.)

So... what should pip be doing differently to make this work?

--
Ian Bicking  |  http://blog.ianbicking.org