<div class="gmail_quote">On Fri, May 11, 2012 at 2:20 PM, Eric V. Smith <span dir="ltr">&lt;<a href="mailto:eric@trueblade.com" target="_blank">eric@trueblade.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The only thing I&#39;m aware of is that I need to look at Martin&#39;s issue of<br>
how do we gradually migrate to PEP 420 namespace packages from the<br>
existing pkgutil and pkg_resources versions of namespace packages. I&#39;ll<br>
do that this weekend.<br></blockquote><div><br>FWIW, setuptools and distribute (and maybe pip) already do the right thing when installing in &quot;single version&quot; mode, which is usually what the distros use.  They would simply need to stop also creating a .pth file (or dummy __init__.py files) when running under 3.3.  They&#39;d also need to be updated to support new-style namespace packages in their source trees.<br>
<br>The implementation of declare_namespace() for 3.3+ would then just be to create a module object (if not present) and set its __path__ to a virtual path object based on the parent.  (Sadly, this can&#39;t be backported since older Pythons require an actual list object...  hmm...  or do they?   Maybe a list *subclass* would work....  must check into that.  If it works back to 2.3 I could backport...  darn, it uses PyList_Size() and PyList_Getitem(), so I&#39;d also need a meta_path hook to trigger updates.  Hm.  Got to think about that some more.)<br>
<br>The only corner case I can think of is mixing __init__ portions with non-__init__ portions.  If you have both, it&#39;s not sufficient to create a simple PEP 420 virtual path, because it won&#39;t include the __init__ portions.  A backport or &quot;transition support&quot; version needs a way to force __init__ portions to be included in the resulting virtual path.  This can&#39;t be done with the current find_loader() protocol, because the finder doesn&#39;t distinguish between package and non-package cases.<br>
<br>If find_loader() always returned a path for a package (even non-namespace packages), then this would allow virtual paths to be made either inclusive or exclusive of __init__ segments.  That is, it would let there be a transition period where you could explicitly declare a namespace to get a mixed namespace, but by default the paths would be exclusive.<br>
<br>I&#39;m not sure if anything I just said is clear without an example, so I&#39;ll throw one in.  Let&#39;s say somebody&#39;s writing code that spans multiple Python versions, and they want their __init__-based namespace packages to work, but be forward compatible with new subpackages using PEP 420 portions.  Basically, they write some code that calls declare_namespace(), which then sets the module&#39;s __path__ to be an &quot;inclusive virtual&quot; path.  This path object is similar to the current virtual path object, except that it *always* uses the second find_loader() return value, even if the first value returned is not None.  Poof!  Instant &quot;transitional&quot; namespace package, backward-compatible with older Python versions, and forward-compatible with PEP 420.<br>
<br>Okay, technically that was more of a rationale than an example, but I hope it&#39;s a bit clearer anyway.  ;-)  For purposes of the PEP, all I&#39;d request changing is asking that find_loader() always return the path of an existing directory in the second return value, even if it&#39;s also returning a loader.  More precisely, if it returns a loader for a package, it should also return the package directory in the second argument.  importlib can still ignore this second argument, but a transitional version of declare_namespace() can use it to implement &quot;mixed mode&quot; namespace packages.  (Which facilitates backporting the mechanism to older setuptools as well - I&#39;ll change the nspkg.pth files to do something like &#39;import pep420; pep420.declare_namespace(&quot;foo&quot;)&#39; and my pep420 module will include its own mixed-mode virtual path support, and emulate find_loader() for the builtin importers in older Pythons.)<br>
<br></div></div>