0

I wanted to reach for a python module outside of my current working directory of my script - *test.py*,
theproject
├── one_folder
│   ├── main.py
│   └── src
│       ├── test.py
└── another_folder_in_root
    ├── moduleiwant.py

I point to the path from the root folder of project
I go:

from another_folder_in_root.moduleiwant import functioniwant

The root folder of the project is in PYTHONPATH, as follows: (I use PyCharm btw.)

['/Users/me/PycharmProjects/theproject/one_folder', ..., 
'/Users/me/PycharmProjects/theproject'

So the root dir of the project is in fact in the pythonpath!

But that doesn't work!

However, if I add the root folder of the project directly to sys.path, it suddenly works. Can you tell me why? This is ridiculous...

michuhu
  • 93
  • 1
  • 1
  • 10
  • 1
    This stuff gets very tricky / frustrating - to do it the way you are currently you'll need to do either from .another_folder_in_root.moduleiwant import functioniwant or from ..another_folder_in_root.moduleiwant import functioniwant - problem is, those can easily break when you deploy. I'd suggest looking into creating a python package and using "__ init __.py" files to create the structure. – Allan Elder Oct 10 '22 at 13:03
  • 1
    `another_folder_in_root`, but python doesn't use *folder*, but *packages*. And if you want a package, you must add `__init__.py` file to the directory (empty is ok) – Giacomo Catenazzi Oct 10 '22 at 13:11
  • Ok, generally yes. But should I add __init__.py on each node of the tree going from root downwards? What if moduleiwant.py was further down the structure of the folders? – michuhu Oct 10 '22 at 13:22
  • 1
    Every directory should have an *\_\_init\_\_.py*, except for the containing directory (i.e. *theproject*, in this case). Also, your *main.py* script should go inside the root directory of the project (and probably *test.py* as well, since that will also need to access the package-tree). Python automatically adds the script directory to the beginning of `sys.path`, so it is essential to put the startup script in the right place if you want the all the imports to work correctly. – ekhumoro Oct 10 '22 at 13:53
  • But even if another_folder_in_root has __init__.py (empty), I still get the error. What should be content of __init__.py then? – michuhu Oct 10 '22 at 13:58
  • 1
    Does this answer your question? [Src layout to dispense .src prefix in imports? Activate venv in PyCharm terminal for development installs](https://stackoverflow.com/questions/62498127/src-layout-to-dispense-src-prefix-in-imports-activate-venv-in-pycharm-terminal) – bad_coder Oct 10 '22 at 15:01
  • 1
    Also https://stackoverflow.com/q/15252040 – bad_coder Oct 10 '22 at 15:03
  • 1
    @michuhu The *\_\_init\_\_.py* files can be empty. If you're still getting an error, it's because your *main.py* file is in the wrong place - it ***must*** go in the root folder (i.e. *theproject*), rather than a subdirectory. – ekhumoro Oct 11 '22 at 13:49

1 Answers1

0

Ok, I've found an alternative solution not taking advantage of sys.path.

stackoverflow.com - sibling-package-imports

However, using it on existing projects might be problematic, since it might crash already existing imports, e.g. when you use folder ambigious name "src" on various levels. You would have to refactor the code and imports.

All in all, it seems that refactoring the project folder structure is essential and inevitable. (Unfortunately,) Anything else is a temporary hack.

michuhu
  • 93
  • 1
  • 1
  • 10