2

Maybe it's not possible (I'm more used to Ruby, where this sort of thing is fine). I'm writing a library that provides additional functionality to docker-py, which provides the docker package, so you just import docker and then you get access to docker.Client etc.

Because it seemed a logical naming scheme, I wanted users to pull in my project with import docker.mymodule, so I've created a directory called docker with an __init__.py, and mymodule.py inside it.

When I try to access docker.Client, Python can't see it, as if my docker package has hidden it:

import docker
import docker.mymodule

docker.Client() # AttributeError: 'module' object has no attribute 'Client'

Is this possible, or do all top-level package names have to differ between source trees?

d11wtq
  • 34,788
  • 19
  • 120
  • 195
  • 1
    You could only do that if `docker` was set up as a namespace package, which it isn't. See [`zope.schema`](https://github.com/zopefoundation/zope.schema/blob/master/setup.py#L93), [`zope.interface`](https://github.com/zopefoundation/zope.interface/blob/master/setup.py#L93), etc. for an example of a namespace package (`zope` is the namespace package here). – Lukas Graf Jun 22 '14 at 09:39
  • @LukasGraf thank you! If you post that as an answer, I'll accept. – d11wtq Jun 22 '14 at 09:43
  • 5
    See [How do I create a namespace package in Python?](http://stackoverflow.com/questions/1675734/how-do-i-create-a-namespace-package-in-python). Also note that since python3.3 there is [built-in support for namespace packages](https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages). – Bakuriu Jun 22 '14 at 09:46

1 Answers1

2

This would only be possible if docker was set up as a namespace package (which it isn't).

See zope.schema, zope.interface, etc. for an example of a namespace package (zope is the namespace package here). Because zope is declared as a namespace package in setup.py, it means that zope doesn't refer to a particular module or directory on the file system, but is a namespace shared by several packages. This also means that the result of import zope is pretty much undefined - it will simply import the top-level module of the first zope.* package found in the import path.

Therefore, when dealing with namespace packages, you need to explicitely import a specific one with import zope.schema or from zope import schema.

Unfortunately, namespace packages aren't that well documented. As noted by @Bakuriu in the comment, these are some resources that contain some helpful information:

Community
  • 1
  • 1
Lukas Graf
  • 30,317
  • 8
  • 77
  • 92