0

I have a project where I want to structure the code in layers. The different parts of the program do very different things, and I wish to have a clean upper layer which binds all of the code in sub-directories together.

However, I struggle with importing modules correctly.

Say I have the structure

Project
└──manage.py
   └──part a
      ├──script_a.py
      ├──__init__.py
      └──modules_a
         ├──module_a1.py
         ├──module_a2.py
         ├──module_a3.py
         └──__init__.py
   └──part b
      ├──script_b.py
      ├──__init__.py
      └──modules_b
         ├──module_b1.py
         ├──module_b2.py
         ├──module_b3.py
         └──__init__.py

If I am writing code in script_a.py that depends on something from module_a1.py I use

from modules_a import module_a1

This works, but VS Code is never happy about the importing, always marking the imports with error. Therefore, I am wondering if there is something that I have logically misunderstood, especially since the script_a.py is not in the root folder?

2 Answers2

0

If you are within a package and you want to access a sub package you have to put a . in front of the sub package. So change your import statement from

from modules_a import module_a1

to

from .modules_a import module_a1

Then the error disappears.

Alex
  • 221
  • 3
  • 11
  • My bad, it didn't have `.py` originally, I have changed the question now. It gives me import error without the file extension. – Fredrik Alvsaker Jun 27 '19 at 08:37
  • Can you post the exact error/warning code of VSCode? Which liniting tools (pylint, mypy, etc.) do you use? Since it's working I don't suspect that there is any severe issue in the way of importing the module. What you can try though is to set the following in your `modules_a/__init__.py` file: `import .module_a1` and see if that makes the error disappear. – Alex Jun 27 '19 at 08:50
  • BTW: I see that you import a module that is not existing. It should be `from modules_a import module_a1` instead of `from modules_a import module_1a` notice the difference between `module_a1` and `module_1a`. Does this fix your issue? If so I will update my answer – Alex Jun 27 '19 at 08:53
  • Adding `import .module_a1` gave error `invalid syntax (, line 1)pylint(syntax-error)`. I am using pylint, but have tried disabling `"python.jediEnabled": false` in settings.json without the problem going away. The error presented in the code (same line as the import) is `No name 'module_a1' in module 'modules_a''pylint(no-name-in-module)`. – Fredrik Alvsaker Jun 27 '19 at 09:02
  • Sorry, clumsily written question. The names are just dummy names, so there is no difference between `module_1a` and `module_a1`. I will update the question. – Fredrik Alvsaker Jun 27 '19 at 09:03
  • I get an `ImportError` when using `.modules_a`, which says `attempted relative import with no known parent package`. – Fredrik Alvsaker Jun 27 '19 at 09:51
  • Thank you for your time, Alex. I have decided to work around the problem by only running tests from the root folder, as mentioned in my answer. – Fredrik Alvsaker Jun 27 '19 at 11:02
  • Sure, you're welcome! But in regards to your problem: The execution of scripts depends on the path's context in order to resolve relative paths. Maybe the following answer might solve your problem: https://stackoverflow.com/a/49375740/5734066 You might give it a try. But I'm glad you have found a workaround! – Alex Jun 27 '19 at 11:12
0

I decided to solve it by adding a testing file in the root folder and only running the script from the testing file, which will have similar functionality to the manage.py that will be my execution script later.