-1

Here's a file structure I'm working with:

package_example/
  main.py
  the_package/
    __init__.py
    pkg_file_1.py
    pkg_file_2.py

Here are the files:

# main.py
from the_package.pkg_file_1 import foo_1


def main():
    foo_1()


if __name__ == "__main__":
    main()
# pkg_file_1.py
from the_package import pkg_file_2


def foo_1():
    print("this is the second version, foo_1")
    pkg_file_2.foo_2()


if __name__ == "__main__":
    foo_1()
# pkg_file_2.py

def foo_2():
    print("this is foo_2")

If I run main.py, everything works fine.

But if I run pkg_file_1.py, I get:

Traceback (most recent call last):
  File "the_package/pkg_file_1.py", line 1, in <module>
    from the_package import pkg_file_2
ModuleNotFoundError: No module named 'the_package'

Obviously in this simplified example, it doesn't matter, since main.py and pkg_file_1.py run the same code.

But practically, I have test scripts baked into my package structure, so I can test the code in my new environment and data. But I'm scratching my head on how I'm supposed write import statements such that I don't get a ModuleNotFoundError from both inside or outside the package.

Edit: From pavel's suggest I tried changing pkg_file_1.py to:

from ..the_package import pkg_file_2


def foo_1():
    print("this is the second version, foo_1")
    pkg_file_2.foo_2()


if __name__ == "__main__":
    foo_1()

But running that same file gives:

Traceback (most recent call last):
  File "the_package/pkg_file_1.py", line 1, in <module>
    from ..the_package import pkg_file_2
ImportError: attempted relative import with no known parent package
CSStudent7782
  • 618
  • 1
  • 5
  • 21
  • How about `from ..the_package import pkg_file_2` since it's one level up? – NotAName Aug 30 '21 at 23:45
  • 1
    The way PyCharm and (i believe VSCode as well) work around is by adding root directory of a project to Pythonpath in which case your imports would work just fine. – NotAName Aug 30 '21 at 23:48
  • @pavel see edit. – CSStudent7782 Aug 30 '21 at 23:48
  • Actually just one dot in front. My typo – NotAName Aug 30 '21 at 23:50
  • @pavel Is there a Pythonic way to achieve that? Because if I add it with sys.path I get warnings about having import statements below non-import code. – CSStudent7782 Aug 30 '21 at 23:50
  • @pavel Traceback (most recent call last): File "the_package/pkg_file_1.py", line 1, in from .the_package import pkg_file_2 ImportError: attempted relative import with no known parent package – CSStudent7782 Aug 30 '21 at 23:52
  • This has been covered a zillion times on stack overflow. You can't run submodules directly as scripts when using relative imports. The duplicate, which is the first search result for the error message you got (`ImportError: attempted relative import with no known parent package`) describes why in extensive detail, and shows the alternative approach using `python -m pkg.submodule`. – wim Aug 30 '21 at 23:57

1 Answers1

1

This is why we need relative import.

# pkg_file_1.py
from . import pkg_file_2
...

How to run main.py and pkg_file1.py from package_example dir:

python3 main.py
python3 -m the_package.pkg_file1
Hai Vu
  • 37,849
  • 11
  • 66
  • 93