25

I'm attempting to import a script from my Items file but I keeps on getting an error

from .Items.Quest1_items import *

gives

from .Items.Quest1_items import *
# ImportError: attempted relative import with no known parent package

# Process finished with exit code 1

Here my project tree, I'm running the script from the main.py file

Quest1/
|
|- main.py
|
|- Items/
| |- __init__.py
| |- Quest1_items.py

JayRizzo
  • 3,234
  • 3
  • 33
  • 49
ElLoko 233
  • 473
  • 1
  • 5
  • 11

3 Answers3

23

Remove the dot from the beginning. Relative paths with respect to main.py are found automatically.

from Items.Quest1_items import *
JayRizzo
  • 3,234
  • 3
  • 33
  • 49
Xorekteer
  • 284
  • 2
  • 4
14

You can only perform relative import (ie., starting with a dot), inside a package that you import. For instance, imagine the situation:

project/
├ main.py
├ mylib/
├ __init__.py
│ ├ module1.py
│ └ module2.py

in main.py, you would have import mylib or from mylib import *, but inside module1.py, you could have from . import module2, because here the . stands for mylib (which is a python package, because you imported it within main.py).

So, the solution is simply remove the dot, it's not useful in your situation.

jthulhu
  • 7,223
  • 2
  • 16
  • 33
  • i have an exact directory tree like you said but i still get "ImportError: attempted relative import with no known parent package" – Reza Feb 27 '21 at 18:52
  • 1
    @Reza I re-tryed this minimalistic example (with the exact files, and no code besides the imports) and it works. To locate the origin of your problem, try reducing the size of your program by removing parts until you don't get the error anymore. If you post exactly when the problem arises, I might help you more (import errors can have lots of different causes). Just as a hint, your error might be due to importing a module before the parent package (ie. `import module1` before `import mylib` will not work because `.` doesn't mean anything yet). – jthulhu Feb 28 '21 at 10:24
  • sry @BlackBeans it was my bad. I was trying to run module1.py directly(`python module1.py`) but i had forgotten that i should run it like this: `python -m mylib.module1` – Reza Mar 03 '21 at 10:11
7

To put it simply: if you use relative import, you can run the file you want to run with 'python -m your_module_path' on the two layers above the outermost file used by your code.

Like the following, if you want to run run.py, you need to go to two layers above it, then run python -m dir1.dir2.run(without .py).

.../dir1/dir2/
    -test
        -test1.py
            from .test2 import *
        -test2.py
    -run.py
        from .test.test1 import *
fitz
  • 540
  • 4
  • 11
  • 4
    The alternative is to "turn your code into a package", which means **all of** 1) putting an `__init__.py` in the top dir of your code **and** 2) adding the parent directory of the top dir to your `PYTHONPATH` **and** 3) setting the `__package__` variable in your Python program to the name of the directory that contains `__init__.py`. Then your code thinks it's in a package and can be run without `-m`. – AstroFloyd May 20 '21 at 11:51