[Python-Dev] PEP 382: Namespace Packages

glyph at divmod.com glyph at divmod.com
Fri Apr 17 05:58:22 CEST 2009


On 16 Apr, 03:36 pm, pje at telecommunity.com wrote:
>At 03:46 AM 4/16/2009 +0000, glyph at divmod.com wrote:
>>On 15 Apr, 09:11 pm, pje at telecommunity.com wrote:

>>Twisted has its own system for "namespace" packages, and I'm not 
>>really sure where we fall in this discussion.  I haven't been able to 
>>follow the whole thread, but my original understanding was that the 
>>PEP supports "defining packages", which we now seem to be calling 
>>"base packages", just fine.
>
>Yes, it does.  The discussion since the original proposal, however, has 
>been dominated by MAL's counterproposal, which *requires* a defining 
>package.

[snip clarifications]
>Does that all make sense now?

Yes.  Thank you very much for the detailed explanation.  It was more 
than I was due :-).
>MAL's proposal requires a defining package, which is counterproductive 
>if you have a pure package with no base, since it now requires you to 
>create an additional project on PyPI just to hold your defining 
>package.

Just as a use-case: would the Java "com.*" namespace be an example of a 
"pure package with no base"?  i.e. lots of projects are in it, but no 
project owns it?
>>I'd appreciate it if the PEP could also be extended cover Twisted's 
>>very similar mechanism for namespace packages,

>>"twisted.plugin.pluginPackagePaths".  I know this is not quite as 
>>widely used as setuptools' namespace package support, but its 
>>existence belies a need for standardization.
>>
>>The PEP also seems a bit vague with regard to the treatment of other 
>>directories containing __init__.py and *.pkg files.
>
>Do you have a clarification to suggest?  My understanding (probably a 
>projection) is that to be a nested namespace package, you have to have 
>a parent namespace package.

Just to clarify things on my end: "namespace package" to *me* means 
"package with modules provided from multiple distributions (the 
distutils term)".  The definition provided by the PEP, that a package is 
spread over multiple directories on disk, seems like an implementation 
detail.

Entries on __path__ slow down import, so my understanding of the 
platonic ideal of a system python installation is one which has a single 
directory where all packages reside, and a set of metadata off to the 
side explaining which files belong to which distributions so they can be 
uninstalled by a package manager.

Of course, for a development installation, easy uninstallation and quick 
swapping between different versions of relevant dependencies is more 
important than good import performance.  So in that case, you would want 
to optimize differently by having all of your distributions installed 
into separate directories, with a long PYTHONPATH or lots of .pth files 
to point at them.

And of course you may want a hybrid of the two.

So another clarification I'd like in the PEP is an explanation of 
motivation.  For example, it comes as a complete surprise to me that the 
expectation of namespace packages was to provide only single-source 
namespaces like zope.*, peak.*, twisted.*.  As I mentioned above, I 
implicitly thought this was more for com.*, twisted.plugins.*.

Right now it just says that it's a package which resides in multiple 
directories, and it's not made clear why that's a desirable feature.
>>   The concept of a "defining package" seems important to avoid 
>>conflicts like this one:
>>
>>    http://twistedmatrix.com/trac/ticket/2339

[snip some stuff about plugins and package layout]
>Namespaces are not plugins and vice versa.  The purpose of a namespace 
>package is to allow projects managed by the same entity to share a 
>namespace (ala Java "package" names) and avoid naming conflicts with 
>other authors.

I think this is missing a key word: *separate* projects managed by the 
same entity.

Hmm.  I thought I could illustrate that the same problem actually occurs 
without using a plugin system, but I can actually only come up with an 
example if an application implements multi-library-version compatibility 
by doing

    try:
        from bad_old_name import bad_old_feature as feature
    except ImportError:
        from good_new_name import good_new_feature as feature

rather than the other way around; and that's a terrible idea for other 
reasons.  Other than that, you'd have to use 
pkg_resources.resource_listdir or somesuch, at which point you pretty 
much are implementing a plugin system.

So I started this reply disagreeing but I think I've convinced myself 
that you're right.
>Precisely.  Note, however, that neither is twisted.plugins a namespace 
>package, and it should not contain any .pkg files.  I don't think it's 
>reasonable to abuse PEP 382 namespace packages as a plugin system.  In 
>setuptools' case, a different mechanism is provided for locating plugin 
>code, and of course Twisted already has its own system for the same 
>thing. It would be nice to have a standardized way of locating plugins 
>in the stdlib, but that will need to be a different PEP.

Okay.  So what I'm hearing is that Twisted should happily continue using 
our own wacky __path__-calculation logic for twisted.plugins, but that 
*twisted* should be a namespace package so that our separate 
distributions (TwistedCore, TwistedWeb, TwistedConch, et. al.) can be 
installed into separate directories.


More information about the Python-Dev mailing list