0

I am looking for a easy way to import functions from another folder:

|--mylib
|   |--__init__.py
|   |--mylib2.py
|
|--mytest
|   |--other.py
|   |--test_one.py
|
|--mymain.py

mylib2.py

def suma(a,b):
    return a+b

mymain.py

from mylib.mylib2 import suma
def main():
    a=3
    b=4
    c=suma(a,b)
    print(c)


if __name__ == "__main__":
    main()

other.py

from mylib.mylib2 import suma

c=suma(1,2)
print(c)

test_one.py

from mylib.mylib2 import suma

def test_nothing():
    assert True

def test_crash():
    e=0
    #d=30/e
    assert True

For some reason I can not call suma from other.py normally (because I don't know how to properly include mylib2.py in a file from mytest folder but following this answer I could do

python3 -m mytest.other
3

The problem is that I don't how to run the pytest including the library

if I do pytest I got a message

    from mylib.mylib2 import suma
E   ModuleNotFoundError: No module named 'mylib'

How can I run the test in a simple way?

KansaiRobot
  • 7,564
  • 11
  • 71
  • 150
  • How about simply appending the __sys.path__? `import sys; sys.path.append('../mylib')` on `other.py` – Jiho Choi Oct 24 '22 at 08:53
  • 1
    @JihoChoi In my experience, messing around with `sys.path` can lead to lots of issues, especially when you're cooperating with team members. See this thread: https://stackoverflow.com/questions/69300985/how-to-import-file-in-python-with-changed-entry-point-sys-path – hide1nbush Oct 24 '22 at 09:11
  • @hide1nbush My thoughts exactly. Unfortunately my code is part of a much bigger code with many members. I don't want to mess with `sys.path` – KansaiRobot Oct 24 '22 at 09:21

1 Answers1

3

TL;DR: You should also add __init__.py inside mytest folder.

Explanation:

It's easy to misunderstand the concepts between module and package. I'm still not sure that I have fully understanding them even after years programming on Python. Plz correct me if I'm wrong.

  1. If mytest folder don't have __init__.py, the interpreter will consider mylib as a package, similar to numpy, pandas, when executing the pytest command. The searching process is based on your PYTHONPATH. However, you didn't technically install mylib package, so the interpreter will raise error like: ModuleNotFoundError: No module named 'mylib'.

  2. By adding __init__.py, pytest will consider mylib and mytest are as normal modules, so you can import mylib.mylib2 as usual.

Further reading:

Relative imports for the billionth time

Pytest: how to work around missing __init__.py in the tests folder?

hide1nbush
  • 759
  • 2
  • 14
  • WOW! this worked and I don't know why or how, so I am looking forward to your explanation. Thousand thanks! – KansaiRobot Oct 24 '22 at 08:50
  • The funny thing is that pytest works now. but still `other.py` has to be called as `python3 -m mytest.other`, because otherwise it will say "no module named 'mylib' – KansaiRobot Oct 24 '22 at 09:25
  • @KansaiRobot yup. if you add `import sys` and `print(sys.path)` before `from mylib.mylib2 import suma`, you can see that the `PATH` doesn't include `mylib` when running `python3 -m other` inside `mytest` folder. You can either 1. run `python3 -m mytest.other` under root folder, or 2. using relatively import, see this thread: https://stackoverflow.com/questions/16981921/relative-imports-in-python-3 – hide1nbush Oct 24 '22 at 09:37