Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python3 relative imports failing in package

I've been reading tons of questions related to this matter but none of the has help me so far. I'm currently using the Python click library to execute scripts as commands.

The current command that I'm trying to execute is placed inside a Python Package which has a __main__.py file, like the parent dir has. The current project structure is the following one.

/myproject
   /foo_one
       __init__.py
       foo_one.py
    /foo_two
       __init__.py
       foo_two.py
    /foo_three
       __init__.py
       foo_three.py
    /foo_four
       __init__.py
       foo_four.py
    /foo_five
       __init__.py
       foo_five.py
    /foo_six
       __init__.py
       foo_six.py
    __init__.py
    __main__.py
    foo_seven.py

Whenever I try to run the __main__.py script located in the project folder, the following error comes up.

ModuleNotFoundError: No module named '__main__.foo_two'; '__main__' is not a package

However, if I try to execute that same script from a folder above with the -m option like this python3 myproject -m, the following is shown up.

ImportError: attempted relative import with no known parent package

The __main__.py has 2 imports like this... The __init__.py is empty.

from .foo_two.foo_two import AClass, AnotherClass, OtherClass
from .foo_three.foo_three import AnotherClassMore

UPDATE: Correcting the syntax error in a previous command, while calling python -m myproject gives me a ModuleNotFoundError because of a module that isn't my responsibility, which is basically a library that is used in the project.

like image 367
Lenny D. Avatar asked Dec 02 '22 11:12

Lenny D.


2 Answers

Hopefully, this will be of value to someone out there - I went through half a dozen stackoverflow posts trying to figure out relative imports similar to whats posted above here. I set up everything as suggested but I was still hitting ModuleNotFoundError: No module named 'my_module_name'

Since I was just developing locally and playing around, I hadn't created/run a setup.py file. I also hadn't apparently set my PYTHONPATH.

I realized that when I ran my code as I had been when the tests were in the same directory as the module, I couldn't find my module:

$ python3 test/my_module/module_test.py                                                                                                               2.4.0
Traceback (most recent call last):
  File "test/my_module/module_test.py", line 6, in <module>
    from my_module.module import *
ModuleNotFoundError: No module named 'my_module'

However, when I explicitly specified the path things started to work:

$ PYTHONPATH=. python3 test/my_module/module_test.py                                                                                                  2.4.0
...........
----------------------------------------------------------------------
Ran 11 tests in 0.001s

OK

So, in the event that anyone has tried a few suggestions, believes their code is structured correctly and still finds themselves in a similar situation as myself try either of the following if you don't just add your export the current directory to your PYTHONPATH:

  1. Run your code and explicitly include the path like so: $ PYTHONPATH=. python3 test/my_module/module_test.py
  2. To avoid calling PYTHONPATH=., create a setup.py file with contents like the following and run python setup.py development to add packages to the path:
# setup.py
from setuptools import setup, find_packages

setup(
    name='sample',
    packages=find_packages()
)
like image 100
LaCroixed Avatar answered Dec 04 '22 08:12

LaCroixed


The correct syntax would be

python -m myproject

This should execute __main__ in the top-level package.

like image 42
Omni Avatar answered Dec 04 '22 07:12

Omni