0

Simple example:

File structure is:

test/lib/f1.py
test/lib/f2.py

File contents:

$ cat lib/f1.py 
from f2 import bar

def foo(a):
  print(1+bar(a))

$ cat lib/f2.py                                                                                                   
def bar(a):
  return a

So f1.py defines foo, which relies on bar, defined in f2.py.

Now, loading f1.py works just fine when inside test/lib/:

$ python3
Python 3.5.2 (default, Nov 12 2018, 13:43:14) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from f1 import foo
>>> foo(1)
2

However, when loading from outside test/lib/ (say from test/), this fails with an import error:

$ python3
Python 3.5.2 (default, Nov 12 2018, 13:43:14) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from lib.f1 import foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/tmp/pymod/lib/f1.py", line 1, in <module>
    from f2 import bar
ImportError: No module named 'f2'
>>> Quit (core dumped)

Moving the code from f2.py in f1.py fixes the issue, but I don't want to do that.

Why am I getting this error and how can I avoid it?

Henry Henrinson
  • 5,203
  • 7
  • 44
  • 76
  • You need an `__init__.py` file (it can be empty but it needs to be there) in `test/lib` - https://docs.python.org/3/reference/import.html#regular-packages – Craicerjack Jul 15 '19 at 10:39
  • 1
    `PYTHONPATH=${PYTHONPATH}:/tmp/pymod/lib python3`, and then type your code in the interpreter console. Or modify the *f1.py* import to `from .f2 import bar`. – CristiFati Jul 15 '19 at 10:40
  • @Craicerjack Good thought, but it doesn't fix the issue. Also, I thought `__init__.py` was optional? – Henry Henrinson Jul 15 '19 at 10:44
  • @HenryHenrinson you learn something new everyday. It seems you are correct - https://stackoverflow.com/questions/37139786/is-init-py-not-required-for-packages-in-python-3-3 – Craicerjack Jul 15 '19 at 10:49
  • @CristiFati Doing `from .f2 import bar` does fix the issue, but it causes a new one. I can no longer do `from f1 import foo` when starting python from inside `lib`. Is there no way around this? – Henry Henrinson Jul 15 '19 at 10:53
  • @HenryHenrinson: Try: `from pymod.lib.f1 import foo`. – CristiFati Jul 15 '19 at 11:04
  • Were you able to run the scripts? – CristiFati Jul 15 '19 at 12:28

1 Answers1

0

Define the folder where it should look for the modules:

import sys
sys.path.append('test')

from lib.f1 import foo
Alex
  • 5,759
  • 1
  • 32
  • 47