0

Here is a project structure just for demonstrating the actual problem

Project/
   +---Scripts/
          +-----module.py
          +-----submodule.py
   +---main.py

submodule.py contains

def a():
    return "Hello World"

module.py contained originally

from submodule import a

def f():
    return a()


if __name__ == "__main__":
    print(f())

You can see this module.py can also be run as a script(which is important for my project)

But if I write main.py as

from Scripts.module import f

print(f())

I am getting an error as

ModuleNotFoundError: No module named 'submodule'

This error generated at module.py, and it is due to the fact that running main.py (instead of module.py changed the import path)

I know, There are two ways to solve it

Option A:

Change the import in module.py as

from Scripts.submodule import a

Now, if I run main.py there are no issues. But if I now run module.py directly I obviously get error as

ModuleNotFoundError: No module named 'Scripts.submodule'

Even though it temporarily solves the problem in main.py, if is still messy, and also both main.py and module.py cannot be run in this method

Option B:

Use relative import in module.py from .submodule import a

Now also if I run main.py there are no issues. But again if I run module.py directly I get error as

ImportError: attempted relative import with no known parent package

I don't understand what am I doing wrong here. I want to be able to run both main.py and module.py without any code change, so that developers who writes the modules can follow the same convention when importing submodules.

I also tried to make a __init__.py both in Project root folder and also in Scripts folder, but still getting the same error when running module.py individually.

Any help is appreciated.

agnim9
  • 1
  • 1
  • The question looks similar to https://stackoverflow.com/q/14132789/407651 (and many other questions too). – mzjn Jun 17 '23 at 11:44
  • Making a module also be a script is fundamentally broken (because then it’s `__main__` rather than the module it is otherwise). It’s not an answer to your question, but it’s not worth fixing this (in the long term). – Davis Herring Jun 17 '23 at 16:34
  • In Option B, it works if you run `python -m Scripts.module` (instead of `python Scripts/module.py`). – mzjn Jun 17 '23 at 17:16

1 Answers1

0

I assumed submodule.py to be like this (because it is not true in the current state!):

# submodule.py

def a():
    return 'hello'

Then I changed module.py like this:

# module.py

from Scripts.submodule import a
   
   ...

It works properly!

  • 1
    I already mentioned that in Option A. If in module.py I write "from Scripts.submodule import a" then I cannot run module.py as a script. I want to be able to run main.py as well as module.py as a script without any code change. – agnim9 Jun 17 '23 at 16:11