2

I followed Python 3 Modules tutorial and I cannot get absolute or relative intra-package imports to work.

Specifically I replicated the project structure from the tutorial. The sound folder is located in my home /home/user/ directory. All project files (excluding filters/vocoder.py and effects/surround.py) are empty and have been generated using touch.

sound/                          Top-level package
      __init__.py               Initialize the sound package
      formats/                  Subpackage for file format conversions
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py

      effects/                  Subpackage for sound effects
              __init__.py
              echo.py
              surround.py
              reverse.py

      filters/                  Subpackage for filters
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py

As per instruction filters/vocoder.py contains:

from sound.effects import echo

When this file is executed, it results in an import error:

user@pc:~/sound$ python filters/vocoder.py
Traceback (most recent call last):
  File "filters/vocoder.py", line 1, in <module>
    from sound.effects import echo
ImportError: No module named 'sound'

user@pc:~/sound$ cd filters/

user@pc:~/sound/filters$ python vocoder.py 
Traceback (most recent call last):
  File "vocoder.py", line 1, in <module>
    from sound.effects import echo
ImportError: No module named 'sound'

Likewise I have executed each of the following lines of code in effects/surround.py separately (I commented the lines out # and rerun the script):

from . import echo
from .. import formats
from ..filters import equalizer

Which when it is executed results in:

user@pc:~/sound$ python effects/surround.py
Traceback (most recent call last):
  File "effects/surround.py", line 1, in <module>
    from . import echo
SystemError: Parent module '' not loaded, cannot perform relative import

user@pc:~/sound$ cd effects/

user@pc:~/sound/effects$ python surround.py
Traceback (most recent call last):
  File "surround.py", line 1, in <module>
    from . import echo
SystemError: Parent module '' not loaded, cannot perform relative import

What am I doing wrong, why can I not get absolute and relative imports to work in my package?

Below is a script which should help replicate the project:

mkdir ~/sound
touch ~/sound/__init__.py

mkdir ~/sound/formats
touch ~/sound/formats/__init__.py
touch ~/sound/folder/wavread.py
touch ~/sound/folder/wavwrite.py
touch ~/sound/folder/aiffread.py
touch ~/sound/folder/aiffwrite.py
touch ~/sound/folder/auread.py
touch ~/sound/folder/auwrite.py

mkdir ~/sound/effects
touch ~/sound/effects/__init__.py
touch ~/sound/folder/echo.py
touch ~/sound/folder/surround.py
touch ~/sound/folder/reverse.py

mkdir ~/sound/filters
touch ~/sound/filters/__init__.py
touch ~/sound/folder/equalizer.py
touch ~/sound/folder/vocoder.py
touch ~/sound/folder/karaoke.py


echo "from sound.effects import echo" >> ~/sound/filters/vocoder.py

echo "from . import echo" >> ~/sound/effects/surround.py
echo "from .. import formats" >> ~/sound/effects/surround.py
echo "from ..filters import equalizer" >> ~/sound/effects/surround.py
Greg
  • 8,175
  • 16
  • 72
  • 125
  • Is your `/home/user` directory on the Python library search path? The documentation you linked to says: "When importing the package, Python searches through the directories on sys.path looking for the package subdirectory." If the directory containing `sound` is not on `sys.path`, `sound` will not be found. – BrenBarn Jul 16 '16 at 05:39
  • I am not sure, how can I check that? Running `printenv PYTHONPATH` did not show any results. – Greg Jul 16 '16 at 05:44
  • You can do `import sys` and then `print sys.path` from inside the Python interpreter. Most likely you would want to create a directory like `/home/mypythonstuff` and then add that to PYTHONPATH. Or you could use the [per-user site-packages directory](https://www.python.org/dev/peps/pep-0370/), which on Unix-like systems is something like `~/.local/lib/python3.5`. – BrenBarn Jul 16 '16 at 05:48
  • Thank you! To confirm, if a module is installed using `python setup.py install`, it gets copied into `~/.local/lib/python3.5` (or the equivalent) and as a result Python finds it? – Greg Jul 16 '16 at 05:54
  • It will actually usually get copied into the global Python module directory (often something like `/usr/local/lib/python3.5/dist-packages`. You can read documentation of [the `site` module](https://docs.python.org/3/library/site.html) for more info on how the path is determined. – BrenBarn Jul 16 '16 at 06:09

1 Answers1

0

I was just looking at the tutorial. I don't read that from sound.effects import echo is supposed to work as is from filters/vocoders.py. What is says there in the tutorial is:

Users of the package can import individual modules from the package, for example:

import sound.effects.echo

So that would be as if a user could reference the sound directory from their current directory. Like some of the comments said, in order to do that, the user needs to either be in the same directory as sound or add the sound directory to your PATH variable. Like this:

import sys
sys.path.append( <path to sound> )
from sound.effects import echo

See also: Import a module from a relative path

Further down the tutorial, they touch on what you are trying to do, which is intra-package references. You could use this technique without adding sound to your PATH:

For example from your filters/vocoders.py module, this should work to import echo:

from ..effects import echo
Community
  • 1
  • 1
jeffery_the_wind
  • 17,048
  • 34
  • 98
  • 160
  • In contrast to your answer, importing modules in such a way is definitely possible as per the tutorial: "For example, if the module sound.filters.vocoder needs to use the echo module in the sound.effects package, it can use from sound.effects import echo." I've also tested it and it worked (after BrenBarn's answer). – Greg Jul 16 '16 at 06:47