1

My directory is as such:

isds:
__init__.py
    jobs:
    __init__.py
        adhoc:
        __init__.py
        test.py
        test2.py

My two files look like this.

test.py:

import sys

x = 10

test2.py:

import sys
from isds.jobs.adhoc.test import *

print(x)

When I run "python3 test2.py" from the same directory as test2.py, I get this error: ModuleNotFoundError: No module named 'isds.jobs.adhoc.test'

Why is this happening? I have the init.py files and I think I have the absolute import statement correct... but maybe not?

Thanks!

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
fjjones88
  • 267
  • 4
  • 16
  • 1
    Because Python has no reason to consider the parent `isds` directory as a place to look for modules or packages. You should use *relative imports* to get code from within the same package. – Karl Knechtel Nov 17 '20 at 04:23
  • 2
    Does this answer your question? [Relative imports in Python 3](https://stackoverflow.com/questions/16981921/relative-imports-in-python-3) – Karl Knechtel Nov 17 '20 at 04:24
  • 1
    Why not use `from test import *` as it's in the same directory – Underoos Nov 17 '20 at 04:28
  • Hey all, yes the {from test import *} did work! So, I know asking another question isn't the best etiquette, but I'm extrapolating to the real issue I'm facing: So, let's say test2.py is located here: "isds.jobs2.adhoc2.test2.py" and assume there are init.py files where there should be. Shouldn't the import statement be "from isds.jobs.adhoc.test import *"? I still get the same error as reported earlier. – fjjones88 Nov 17 '20 at 04:36
  • @fjjones88 the [question linked by Karl](https://stackoverflow.com/questions/16981921/relative-imports-in-python-3) gives the "correct" way of running this using `-m` flag as part of the accepted answer, I have posted the specific use case as an answer here, if you have any further questions or clarifications feel free to comment on my answer. – Tadhg McDonald-Jensen Nov 19 '20 at 02:58

2 Answers2

2

Since you are importing the module from same directory you can simply import using.

from test import *
Hasnat
  • 531
  • 4
  • 8
  • Nice! That worked. So, let's say test2.py is located here: "isds.jobs2.adhoc2.test2.py" and assume there are __init__.py files where there should be. Shouldn't the import statement be "from isds.jobs.adhoc.test import *"? I still get the same error as reported earlier. – fjjones88 Nov 17 '20 at 04:32
  • Python uses relative path in import statement. So, if you are running the file from parent directory of isds. then you have to give the complete path like this isds.jobs2.adhoc2.test2 – Hasnat Nov 17 '20 at 04:40
0

in order to import as a package then you need to run the file as a package, so you would navigate to the folder containing isds` and run:

python -m isds.jobs.adhoc.test2

This runs the file as a module instead of a script, and since it gets indexed at the same level that it uses its own imports then the import mechanic you are using works as intended.

If you want to support either running as a script or running as a module you would need something like this:

try:
    from isds.jobs.adhoc.test import *
except ModuleNotFoundError:
    from test import *

But this can lead to other issues like if a different module not found error occurs and then import test ends up importing something else entirely you can get confusing and misleading error messages, so I'd generally recommend just running all your stuff with the -m flag if you are writing packages.

Also note this method works without any __init__.py files in python 3.7,4. the requirement to add empty init files was removed a while ago I believe.

Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59