<br><br><div class="gmail_quote">On Sun, Jul 10, 2011 at 21:39, P.J. Eby <span dir="ltr">&lt;<a href="mailto:pje@telecommunity.com">pje@telecommunity.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="im">At 11:57 PM 7/10/2011 -0400, P.J. Eby wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
At 01:16 PM 7/11/2011 +1000, Nick Coghlan wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
There&#39;s also a performance impact on app startup time - currently most<br>
package imports stop as soon as they hit a matching directory. Under a<br>
&quot;partitioned by default&quot; scheme, all package imports (including things<br>
like &quot;logging&quot; and &quot;email&quot; which currently get a hit in the first zip<br>
file for the standard library) would have to scan the entirety of<br>
sys.path just in case there are additional shards lying around. For<br>
large applications, that additional overhead is going to add up.<br>
</blockquote>
<br>
Darn, I missed that.  That kills the idea pretty much dead right there, as it means ALL imports are massively slowed down.  Crap.<br>
</blockquote>
<br></div>
Hrm.  I just realized WHY I missed it.  I was thinking that we&#39;d only do that in the case where you *first* find a namespace.  IOW, I was proposing to only change the semantics in the case where a suitable directory is found on sys.path *before* the normal package or module.  IOW, the semantics I was thinking of were:<br>


<br>
 * Scan sys.path, keeping track of any subpaths found<br>
 * If you hit a module with no subpaths found before it, import and finish<br>
 * Otherwise, if you hit a subpath first, accumulate all subpaths and tack them on a module or package<br>
 * If the matching module was a package __init__, move its subpath to the beginning of the list<br>
<br>
But I agree that it&#39;s an upward climb to sell this approach.  For example, it means that you can have code later on sys.path affect code that&#39;s earlier, which seems wrong and a tad unsafe.<br>
<br>
I wish we had a way to do this that didn&#39;t require special files, and still allowed us to have package names be plain directory names, and didn&#39;t break distutils installation processes.  (Distutils can install submodules without a package __init__ being included, but apart from that it forces installed directory structure to match package name structure.)<br>


<br>
Okay, I have an idea.<br>
<br>
Suppose that we reserve a special directory name, like &#39;pypkg&#39;.  And, if a sys.path directory contains a &#39;py-pkg&#39; subdirectory, then any directory in that directory (recursively) is a package following __path__-assembly semantics.<br>


<br>
So, in order to enable new import semantics, you have to install your code to a &#39;py-pkg&#39; directory under a regular sys.path directory...  that&#39;s the only catch.<br>
<br>
*However*, because the distutils actually let you install packages without __init__ modules, you can trick them into installing your otherwise-normal package this way, by the simple expedient of telling the distutils your package name is &#39;py-pkg.foo&#39; instead of &#39;foo&#39;.<br>


<br>
(Note: this is only a hack for 2.x, and setuptools will probably be doing the dirty work of making distutils do this anyway &quot;under the hood&quot;.  For 3.x, we can hopefully assume that the &#39;packaging&#39; folks will enable doing this in a somewhat saner way.)<br>


<br>
Anyway, revising the ongoing example to add the directory and drop the flag files, we get:<br>
<br>
    ProxyTypes-0.9.tgz:<br>
        py-pkg/peak/util/proxies.py<br>
<br>
    Importing-1.10.tgz:<br>
        py-pkg/peak/util/imports.py<br>
<br>
or (combined):<br>
<br>
    site-packages/   (or wherever)<br>
        py-pkg/<br>
            peak/<br>
                util/<br>
                    imports.py<br>
                    proxies.py<br>
            zope/<br>
            ...<br>
<br>
This approach solves several problems at once:<br>
<br>
 1. No flag files<br>
 2. Faster imports (stat instead of listdir)<br>
 3. Directory clearly identified as containing python packages<br>
 4. No need for a special name, these are just regular packages with enhanced import semantics<br>
 5. Distutils can still install it<br>
<br>
Minor downsides:<br>
<br>
 * Flat is better than nested<br>
 * Existing code has to move to take advantage (unless you&#39;re not going to import the code without installing it, in which case you can just tweak your setup.py and not actually move anything)<br></blockquote><div><br>

</div><div>I prefer going with a specifically named file if for any other reason than there will be less broken tools. By shifting everything into a subdirectory you prevent any pre-existing code that scans sys.path from doing anything. But with the special file approach you don&#39;t break those tools in the case of when you didn&#39;t have some package fragment farther down sys.path. Plus you can also use a specially named file instead of allowing for any file name with a specific file ending to achieve the same result (e.g., py.pkg or __init__.part).</div>

</div>