101

I have the following directory:

myProgram
└── app
    ├── __init__.py
    ├── main.py 
    └── mymodule.py

mymodule.py:

class myclass(object):

def __init__(self):
    pass

def myfunc(self):
    print("Hello!")

main.py:

from .mymodule import myclass

print("Test")
testclass = myclass()
testclass.myfunc()

But when I run it, then I get this error:

Traceback (most recent call last):
  File "D:/Users/Myname/Documents/PycharmProjects/myProgram/app/main.py", line 1, in <module>
    from .mymodule import myclass
SystemError: Parent module '' not loaded, cannot perform relative import

This works:

from mymodule import myclass

But I get no auto completion when I type this in and there is a message: "unresolved reference: mymodule" and "unresolved reference: myclass". And in my other project, which I am working on, I get the error: "ImportError: No module named 'mymodule'.

What can I do?

Solomon Ucko
  • 5,724
  • 3
  • 24
  • 45
phez1
  • 1,477
  • 3
  • 14
  • 19
  • https://www.python.org/dev/peps/pep-0366/ – user2357112 Nov 20 '15 at 23:26
  • 26
    I came across the same problem. Apparently running script inside a package is considered as a bad practice, and you cant use relative import in that case. Since your main.py is inside the package app, using relative import will cause error. Use relative import only in modules and run the scripts outside the package. – kanatti Mar 20 '16 at 17:14
  • 6
    Use `python -m package.module` instead of `python package/module.py`. – Bakuriu Sep 14 '16 at 06:53
  • [This](https://stackoverflow.com/a/19190695/7414040) is the answer that solves the problem. – P. Siehr Aug 29 '17 at 08:32
  • Got this in PyCharm when I accidentally ran the current file I was editing instead of my `main.py` launcher. – frmdstryr Dec 02 '17 at 17:08

4 Answers4

56

I had the same problem and I solved it by using an absolute import instead of a relative one.

for example in your case, you may write something like this:

from app.mymodule import myclass

You can see in the documentation.

Note that relative imports are based on the name of the current module. Since the name of the main module is always "__main__", modules intended for use as the main module of a Python application must always use absolute imports.

Edit: If you encounter this error ImportError: No module named 'app.app'; 'app' is not a package, remember to add the __init__.py file in your app directory so that the interpreter can see it as a package. It is fine if the file is empty.

Erman
  • 1,543
  • 17
  • 26
  • 3
    If do this I get another error, a `ImportError: No module named 'app.app'; 'app' is not a package`: https://gist.github.com/anonymous/ac0b7b3c36b0a60be6273394d1ddbdfb – fiatjaf Sep 27 '17 at 19:42
  • @fiatjaf please can you share the structure of your code with us ? – Erman Sep 29 '17 at 16:41
  • Thank you, @Erman. Just did it in a comment on that [gist](https://gist.github.com/anonymous/ac0b7b3c36b0a60be6273394d1ddbdfb#gistcomment-2216728). – fiatjaf Sep 29 '17 at 18:15
  • Have you declare your __init__.py file ? Please make to declare your all your packages inside. – Erman Sep 29 '17 at 20:18
  • 1
    For more infornation about __init__.py file, check this link. https://docs.python.org/3/tutorial/modules.html#packages – Erman Sep 29 '17 at 20:19
  • Good answer! But the quote from the python documentation makes no sense to me. Why should the name `__main__` for the main module necessitate absolute imports for that module? – vlz Jul 15 '20 at 09:12
  • @erman But then why relative import won't work in the first place? [The doc you referenced to](https://docs.python.org/3/tutorial/modules.html#intra-package-references), in its second paragraph of that section, actually mentions "you can also write relative imports..." and then even provides examples. PS: Currently I encounter same issue, and the package is an open source project owned by someone else, so it is inconvenient to go through that entire project to switch existing relative imports into absolute imports. – RayLuo Mar 21 '21 at 10:05
  • @RayLuo, another way could be to change the variable `__path__` in the `__init__.py` file and add the subdirectories you need. But, note that it could affect the future search of module and submodule. You can check its usage here: https://stackoverflow.com/questions/2699287/what-is-path-useful-for – Erman Mar 31 '21 at 00:52
19

I usually use this workaround:

try:
    from .mymodule import myclass
except Exception: #ImportError
    from mymodule import myclass

Which means your IDE should pick up the right code location and the python interpreter will manage to run your code.

thomas
  • 325
  • 3
  • 11
8

if you just run the main.py under the app, just import like

from mymodule import myclass

if you want to call main.py on other folder, use:

from .mymodule import myclass

for example:

├── app
│   ├── __init__.py
│   ├── main.py
│   ├── mymodule.py
├── __init__.py
└── run.py

main.py

from .mymodule import myclass

run.py

from app import main
print(main.myclass)

So I think the main question of you is how to call app.main.

das-g
  • 9,718
  • 4
  • 38
  • 80
mymusise
  • 399
  • 3
  • 9
2

If you go one level up in running the script in the command line of your bash shell, the issue will be resolved. To do this, use cd .. command to change the working directory in which your script will be running. The result should look like this:

[username@localhost myProgram]$

rather than this:

[username@localhost app]$

Once you are there, instead of running the script in the following format:

python3 mymodule.py

Change it to this:

python3 app/mymodule.py

This process can be repeated once again one level up depending on the structure of your Tree diagram. Please also include the compilation command line that is giving you that mentioned error message.

Rebel
  • 472
  • 8
  • 25