1

I've been fighting with this for weeks, read so many (outdated) articles, tried so many different proposed solutions without success. And I still believe I'm not trying to do something difficult...

I have the following folder structure

├── script.py 
├── lib 
│   ├── lonlatboxes.py
│   ├── utils.py

I'm using the folder lib to store some libraries used in script.py.

In utils.py I have

from sqlalchemy import create_engine # python package
from lonlatboxes import lonlatboxes # my module

In lonlatboxes.py I have

lonlatboxes = {
    'Africa': [-26.0, 63.0, -41.0, 37.0],
}

In script.py I do

import lib.utils

And this causes an error

      1 from sqlalchemy import create_engine
----> 2 from lonlatboxes import lonlatboxes
      3 

ModuleNotFoundError: No module named 'lonlatboxes'

I guess because the sys.path is resolved w.r.t. the parent folder and not lib. Note that the lib.utils file is found!

How should I solve this? Or...am I doing something completely against Python imports? I believe adding the path to sys.path should not be the correct solution.

Note that I DON'T want to create a package. I just have a set of scripts and small libraries and want to avoid to put everything into the same folder and instead keep them separated so that I can have more order :)

Droid
  • 61
  • 11
  • Try to add empty __init__.py to the lib folder – Sergey Miryanov Nov 30 '21 at 15:06
  • Maybe try `from lib.lonlatboxes import lonlatboxes` (in `utils.py`)? This seems to work for me. I think this line is called as it was in the `script.py` folder. I think using `lib.` won't borrow you, unless you want the user to directly open `utils.py`. In that case, you can detect it by typing the following in `utils.py`: `if __name__ == "__main__":from lonlatboxes import lonlatboxes else: from lib.lonlatboxes import lonlatboxes` – D_00 Nov 30 '21 at 15:09
  • 1
    the __init__.py does not work. I don't know why it is suggested as solution on many articles, I believe it used to work in the past. – Droid Nov 30 '21 at 16:38

3 Answers3

1

All you need to do is change the second import in utils.py and make it relative to script.py's location:

utils.py

from sqlalchemy import create_engine # python package
from .lonlatboxes import lonlatboxes # my module
martineau
  • 112,593
  • 23
  • 157
  • 280
  • Yes, thank you! I gave the relative import a try in the past but somehow they never worked out. That makes sense. – Droid Nov 30 '21 at 16:47
  • Guido: Indeed, many have problems with relative imports — see [Relative imports for the umpteenth time](https://stackoverflow.com/questions/14132789/relative-imports-for-the-umpteenth-time). – martineau Nov 30 '21 at 16:53
0

try to add this to your script.py

import sys
sys.path.append('..')
import lib.utils

then modify your utils.py import section to:

from sqlalchemy import create_engine
from .lonlatboxes import lonlatboxes
Doggy Face
  • 329
  • 3
  • 11
  • This is exactly what I want to avoid :( Adding the path to `sys.path` from what I read should not be the preferred solution. – Droid Nov 30 '21 at 16:40
0

You could also use the PYTHONPATH environment variable. More on the PYTHONPATH here: https://www.tutorialspoint.com/What-is-PYTHONPATH-environment-variable-in-Python

To set it do the following:

  1. cd in the directory you want to add
  2. Execute one of the following (depending on your shell)
# Linux: 
export PYTHONPATH=$PWD
echo $PYTHONPATH

Command Prompt: 
set PYTHONPATH=%cd%
echo %PYTHONPATH%

Powershell: 
$env:PYTHONPATH=$(Get-Location)
echo $Env:PYTHONPATH
borisdonchev
  • 962
  • 6
  • 17