2

I'm using setup.py to create a package foo and then installing it locally with pip install . in a fresh virtual env (python 2.7). In the virtual env's python interpreter I am able to import foo, but python seems to think foo is more a module than a python package (the package kind with the __init__.py file) because when I try to call into foo's substructure, foo.bar, it gives me an error about the module not having the bar attribute.

For example, I can import foo without issue but if I try and call anything off foo, it fails with error message:

>>> import foo
>>> foo.bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'bar'

Here's the folder structure:

foo/
    foo/
        __init__.py
        bar.py
setup.py

Here's my setup.py file:

from setuptools import setup

setup(
    url='none',
    author='loren',
    name='foo',
    version='1.0.0',
    packages=['foo'],
)

Interestingly, I can import bar with from foo import bar and not only does that work but it then fixes my above error and further calls to foo.bar returning the bar module, but that isn't very useful to me.

What do I need to do to get

>>> import foo
>>> foo.bar

to work properly?

2
  • What are the contents of the __init__.py file? Commented Mar 8, 2017 at 22:21
  • The __init__.py file is empty Commented Mar 8, 2017 at 22:28

1 Answer 1

3

Turns out I didn't understand how imports of Python __init.__.py packages work. I thought all the underlying submodules of a package (like bar) were imported when I imported the top level foo package but that is untrue. Python doesn't import submodules on purpose to prevent loading of things I might not use, especially in big packages.

If I wanted to do something like:

>>> import foo
>>> foo.bar

then all I needed to do was import bar in the __init__.py file of the foo module.

I also learned that all packages are modules, (although not all modules are packages) so that is why my error was complaining about how the module didn't have the attribute.

Sign up to request clarification or add additional context in comments.

1 Comment

You might want to use an explicit relative import from . import bar instead of just import bar in __init__.py, for Python 3 compatibility. (See PEP 328.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.