[Import-SIG] Namespace Packages resolution

Carl Meyer carl at oddbird.net
Tue Mar 13 03:30:14 CET 2012


Thanks Martin for this summary. I do have one question; I'd thought I'd
just wait and see if the upcoming new PEP clarified, but since my
question also shows up as a major item in Nick's list of objections, it
may be worth asking for clarity now:

On 03/12/2012 02:13 PM, "Martin v. Löwis" wrote:
[snip]
> - Importing a module/package keeps iterating over the parent
>   path as before, and keeps with the current precedence:
>   * if foo/__init__.py is found, a regular package is imported
>   * if not, but foo.{py,pyc,so,pyd} is found, a module is
>     imported
>
>   * if not, but foo is found as a directory, it is recorded
>   When search completes without importing a module, but it did
>   find directories, then a namespace package is created. That
>   namespace package
>   * has an __name__ of the first directory that was found
>   * has an __path__ which is the full list of directories
>     that were collected
> 
> Of PEP 402, the following features where rejected:
> - there is no support for code in a namespace package
>   (i.e. you cannot use both foo/ and foo.py, but one
>    will take precedence - depending on which one
>    occurs first on the path)

If there is a "foo/" earlier on sys.path and a "foo.py" later, which
wins? This last parenthetical seems to say that the earlier "foo/" would
win, but the more thorough precedence description above indicates that
the later "foo.py" would (because the creation of a namespace package
only kicks in if no other module is importable anywhere on sys.path).

Here is a more precise pseudocode description of how I understand the
proposed algorithm, assuming that someone tries to import "foo".
Hopefully someone involved in the conversation can correct this if it is
wrong:

  namespace_paths = []
  for entry in sys.path:
      if isfile("{entry}/foo/__init__.py"):
          # import and return the old-style package
      elif isfile("{entry}/foo.py"):
          # import and return the module
      elif isdir("{entry}/foo/"):
          namespace_paths.append("{entry}/foo/")
  # no regular module/package was importable anywhere on sys.path
  # return a namespace module with __path__ = namespace_paths

If this is indeed the proposed algorithm, then I think the "backwards
compatibility" item on Nick's list of objections is unfounded. The new
behavior will only occur in situations that would previously have
resulted in an ImportError.

Carl

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/import-sig/attachments/20120312/e5f0f699/attachment.pgp>


More information about the Import-SIG mailing list