0

I'm trying to create a python package, and I have have trouble with the imports. My code works as expected when running it, but when I install the package using poetry and import it in another script, I have a ModuleNotFoundError.

My file structure is the following :

git_repo
|  myapp
|  |--__init__.py
|  |--mainscript.py
|  |--library
|  |  |--__init__.py
|  |  |--module.py

My file mainscript.py imports the module.py because there are some utility functions : from library import module

When I execute the mainscript, no problem. However, when installing myapp using poetry install and trying to import it in a python shell :

> python

>>> import myapp.mainscript

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\path\to\mainscript.py", line 5, in <module>
    from library import module
ModuleNotFoundError: No module named 'library'

Is there a mechanic I don't understand with the imports ? Do I have to write something in the __init__.py files ?

Thanks in advance for your help

2 Answers2

2

there are some utility functions: from library import module

You want:

from .library import module

https://docs.python.org/3/reference/import.html#package-relative-imports

https://docs.python.org/3/reference/simple_stmts.html#import

https://realpython.com/python-import/#absolute-and-relative-imports

J_H
  • 17,926
  • 4
  • 24
  • 44
  • Thanks for your answer. Unfortunately, this does not work. When I make your change and run my script, I get `ImportError: attempted relative import with no known parent package` and when I run it with `python -m` I get `Relative module names not supported`. I will keep digging this way though – Keith_Maxwell Dec 13 '20 at 10:45
  • 1
    Yes, I understand. What matters is _how_ you invoke the program. You must `cd ..` so you're up at the git_repo level. Then "myapp" and "myapp.library" will be visible to the interpreter. If you start too far down, the interpreter doesn't see that "myapp" is a module. Remember that `.` is shorthand for `myapp`, here. Using `-m myapp` is a fine alternative, but the same restriction applies to it, as well, so your starting directory matters. (You might find it convenient to write a brief Bourne script that invokes correctly, to save typing. Or a `make` target.) Also, `export PYTHONPATH=.` helps. – J_H Dec 13 '20 at 18:58
1

Okay so I found a solution to my own problem.

As J_H suggested, I tried relative imports. This worked when installing my package and using it. But I encountered ImportError: attempted relative import with no known parent package when running my mainscript.

The solution was to use absolute imports. Now this works both when installing the package and running the mainscript.

# mainscript.py
from myapp.library import module

I also added some imports in the __init__.py files in order to ease the use of my package when installed :

# myapp/__init__.py
from . import library
from .mainscript import mainClass

This allows me to do a = myapp.mainClass() instead of a = myapp.mainscript.mainClass()