1

I have this directory structure

src
|
|\Lib
| |__init__.py
| |utils.py
|  \Scripts
|   |__init__.py
|   |myscript.py
|__init__.py

and I need to import utils.py in myscript.py but from ..utils import function is giving me

ImportError: attempted relative import with no known parent package

so my attempt is to add the parent package to the path by doing

import sys
from pathlib import Path
sys.path.append(str(Path(__file__).resolve().parents[1]))

inside the innermost __init__.py (under the Scripts folder) without any success.

What am I missing here?

Antonio Santoro
  • 827
  • 1
  • 11
  • 29
  • how are you running the code? can you show how you run myscript.py? the package structure looks good to me it seems like you are using interactive python in some way? – gioxc88 May 04 '21 at 10:51
  • I'm running `myscript.py` from the `Lib` folder – Antonio Santoro May 04 '21 at 10:54
  • If you run it from the lib folder then it cannot work. Your root package is `src` – gioxc88 May 04 '21 at 10:55
  • so what does it mean? – Antonio Santoro May 04 '21 at 10:57
  • It's not clear what are you trying to do. Are you trying to do something like in the terminal `../src/Lib> python myscript.py` – gioxc88 May 04 '21 at 11:01
  • I fixed my question because I was missing a folder – Antonio Santoro May 04 '21 at 11:02
  • As I said I asked clarification on what you are trying to do. My guess is that you are trying to run the python module as a script from the terminal as I explained in the above comment. This won't work because relative imports don't work is the module is invoked as a script. See here for more detailed https://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time. The solution is to move the script outside the package. – gioxc88 May 04 '21 at 11:33
  • I need to run a function defined in `utils.py` from `myscript.py` – Antonio Santoro May 04 '21 at 11:41

1 Answers1

1

My suggestion to have a good understanding of how to deal with this kind of problem is to read this post: Relative imports for the billionth time

One solution to your problem could be the following:

  1. Have this folder structure
src
|
|\Lib
| |__init__.py
| |utils.py
|  
|\Scripts
| |myscript.py
  1. Keep this in your myscript.py
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).resolve().parents[1]))

and change from ..utils import function to from Lib.utils import function

This is one way to solve it.

gioxc88
  • 349
  • 1
  • 9
  • The solution 2 gives me `ModuleNotFoundError: No module named 'Lib.utils'` – Antonio Santoro May 04 '21 at 11:55
  • be sure is `from Lib.utils import function` with capital L and that the this line is put after `sys.path.append(str(Path(__file__).resolve().parents[1]))` – gioxc88 May 04 '21 at 11:59
  • I see. It works for me so I am pretty sure you are doing something different. Lib and Scripts are at the same level under src. can you write how you execute the script? If that doesn't work you maybe someone else can help Cheers – gioxc88 May 04 '21 at 12:12
  • `Lib` and `Scripts` are not at the same level, `Scripts` is contained inside `Lib`, I cannot change the directory structure. Sorry, I misunderstood your solution. – Antonio Santoro May 04 '21 at 12:13
  • In this case there is no solution to your problem. – gioxc88 May 04 '21 at 12:18
  • may I ask you why – Antonio Santoro May 04 '21 at 12:20
  • as I explained I suggested to read this post where it's explained in detail: https://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time. The solution proposed there is the same one I proposed. If you read that post you'll understand. You need to change the folder structure in order to make it work. That's the way python import system works – gioxc88 May 04 '21 at 12:23
  • Running using `python -m src.Lib.Scripts.myscript` will not throw any error on `from ..utils import function`, so what's the point of using the `sys.path.append(str(Path(__file__).resolve().parents[1]))` trick? – Antonio Santoro May 04 '21 at 14:10