1

There is the following structure:

project/
   I-----main.py
   I-----src/
          I----__init__.py (empty)
          I----util.py
          I----shared/
                  I----__init__.py (empty)
                  I----hello.py 


#main.py
from src import util

#util.py (runs without errors)
from shared import hello

#hello.py (runs without errors)
def hello():
    print("Hello")

I try to run main.py, get result

ModuleNotFoundError: No module named 'shared'

How to repair imports in main.py?

Chandella07
  • 2,089
  • 14
  • 22
kostya
  • 27
  • 7
  • Why are there two ``__init__.py``s? Please check https://stackoverflow.com/questions/2164258/is-it-not-possible-to-define-multiple-constructors-in-python – new Q Open Wid May 21 '21 at 11:53
  • 1
    @newQOpenGLWidget one `__init__.py` per package, that looks correct to me. `__init__.py` is **not** a constructor. – SuperStormer May 21 '21 at 11:55

4 Answers4

1

You probably want to from src.shared import hello

DSteman
  • 1,388
  • 2
  • 12
  • 25
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - [From Review](/review/low-quality-posts/29025223) – mufazmi May 21 '21 at 18:25
  • @mufazmi: This one does provide an answer. That said, [subsequently contributed answers](https://stackoverflow.com/a/67636545/3025856) reiterate this suggestion but with a lot more detail. – Jeremy Caney May 21 '21 at 18:55
  • it isnt a stable and always working solution – kostya May 28 '21 at 10:27
1

There are two main reasons for such kind of failures:

  1. Module import: You are not importing the module correctly. You can either import it using the __init__.py of a module by mentioning the import of its sub-module or you can directly put the full path via an import. For instance, you can use from src.shared import hello. Or, in your __init__.py file, inside the src module, you could add from shared import hello. This will also work because whenever you import a module, the first thing that is being run in that module is the __init__.py of that file.

  2. Circular imports: This is not your case, but I am bringing this up because many times we ignore this and get trapped. A circular import occurs when two modules depend on each other. I have described why it happens and how to avoid it in the post, What is Circular Import and how to avoid it.

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
Pratap Alok Raj
  • 1,098
  • 10
  • 19
0

i found possible solution (works well):


    #util.py
    import sys
    from pathlib import Path
    
    root = Path(__file__).parent.parent #depends on file's place in general structure
    sys.path.append(str(root))
    import src.shared.hello as hello

kostya
  • 27
  • 7
-1

You need to use a relative import:

from .shared import hello

If you run util.py normally, .../project/src is appended to sys.path and Python can find the import. However, when you run main.py, .../project/ is appended to sys.path, and Python can't find the shared module. By using a relative import, Python looks up the module name relative to the current package, and can find the shared module.

See also: Relative imports for the billionth time

SuperStormer
  • 4,997
  • 5
  • 25
  • 35