1

I have a folder, which contains two separate folders, one of which holds some python modules, and the other one holds a python script that uses those modules:

parentFolder/
    lib/
       __init__.py
       readFile.py
       writeFile.py
    folder/
       run.py

The __init__.py file is empty. In run.py, I have the following:

from ..lib import readFile

data = readFile('file.dat')

This gives me the error

Traceback (most recent call last):
  File "run.py", line 1, in <module>
    from ..lib import readFile
ValueError: Attempted relative import in non-package 

What am I missing?

sodiumnitrate
  • 2,899
  • 6
  • 30
  • 49

1 Answers1

0

You need to add __init__.py files (can be empty) to each of the directories to make them a package. See the documentation for more details.

plamut
  • 3,085
  • 10
  • 29
  • 40
  • Which directories do you mean? – sodiumnitrate Aug 10 '15 at 15:10
  • To both directories that don't have them yet, i.e. `parentFolder` and `folder`. This is needed to tell Python that the directories are actually code packages ([documentation](https://docs.python.org/2/tutorial/modules.html#packages)) – plamut Aug 10 '15 at 15:12
  • Why does `folder` need one? `run.py` will not be imported by anything. – sodiumnitrate Aug 10 '15 at 15:13
  • Added `__init__.py` to both, and I'm still getting the same error. – sodiumnitrate Aug 10 '15 at 15:15
  • How do you run your code? I searched around a bit and [this question](http://stackoverflow.com/questions/72852/how-to-do-relative-imports-in-python#comment5699857_73149) seems almost identical to yours. Try using the -m switch – plamut Aug 10 '15 at 15:18
  • I edited my previous comment, posted a link to the similar question. Try using the -m switch (python -m run.py). – plamut Aug 10 '15 at 15:23
  • With both the `__init__.py` files in place and using the `-m` switch? Also try to run it from a top-level dir if it matters... – plamut Aug 10 '15 at 15:30
  • Yes. When I'm in the top dir `parentFolder`, I do `python -m folder/run.py`, which gives me `/usr/local/opt/python/bin/python2.7: Import by filename is not supported.` – sodiumnitrate Aug 10 '15 at 15:34
  • Ah, you need to omit the .py suffix: `python -m folder/run`. However, this will give you the "Attempted relative import in non-package". Trying `python -m folder.run` will yield another relative import-related error.This works, however (from outside of parentFolder): `python -m parentFolder.folder.run` - the code will run, but throw an error, because you are trying to call a module - `readFile('file.dat')`, but you'll know how to fix that. ||| My sugestion would be to revert to absolute imports, avoiding all the hassle. – plamut Aug 10 '15 at 16:18
  • Alright, thanks! Do you think it is a good practice to create links to the files in `lib`? – sodiumnitrate Aug 10 '15 at 16:39
  • Sorry, I don't think I understand, what links, can you elaborate please? Soft links on the file system? It's probably better to create a separate `assets` folder inside the package, holding the necessary non-code files your package needs to work. – plamut Aug 10 '15 at 16:49