nckstr15
nckstr15

Reputation: 109

Python ModuleNotFoundError - import from subdir to subdir

First of all: I know there are a lot of questions about this, however none of the ones I ffound are solving my problem.

Setup

I have the following folder structure:

WorkingDirectory(WD)
                   |---------- data
                   |              |
                   |              |-- __init__.py (empty)
                   |              |-- dataset.py (with import: from software.utils import *)
                   |              |-- test.ipynb (with import: from dataset import *)
                   |
                   |-------software
                   |              |
                   |              |-- __init__.py (empty)
                   |              |-- utils.py (with import: from software.utils import *)
                   |
                   |-- main.py (with imports from software and data)

And the following pythonm versions:

Problem

If I run python main.py I do not get any errors, but if I try to execute from dataset import * in the test.ipynb-file I get the error:

ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-4-a20c81312677> in <module>
----> 1 from dataset import *

~/WD/data/dataset.py in <module>
     15 
     16 
---> 17 from software.utils import *

ModuleNotFoundError: No module named 'software'

So in general the import from dataset.py is working, but the "sub-import" from software.utils.py is not working. I am not sure if this is a ipython problem, because it is working with python (it is working if I execute main.py)?

Upvotes: 0

Views: 203

Answers (2)

bigyanse
bigyanse

Reputation: 304

The main problem seems to be as indicated the module cannot be imported because of path issues. It seems to have arised because you referenced the import that begins from the parent directory but you cannot as you are inside a directory inside the parent directory.

You can use this before all of your code in test.ipynb,

import os, sys
currentdir = os.path.dirname(os.path.realpath(__file__))
parentdir = os.path.dirname(currentdir)
sys.path.append(parentdir)

This code basically appends the path of your parent directory so you can import without problem. The good practices at least what I have heard is not to play around with sys.path , but since the need arised, it gets the job done. If you can, I advise you to change a structure a bit.

Upvotes: 1

FloWil
FloWil

Reputation: 442

Usually these kinds of problems evolve around the implicit addition of the current working dir to sys.path e.g. the python package search path.
Put an

import sys

print(sys.path)

and see how the two outputs differ between the regular python call and through Jupyter. The regular python call will probably have your WD in there implictely or by calling through the -m flag of the interpreter and Jupyter Notebook will have not. The only clean way of fixing this is to have a consistent way of calling your scripts. Either add some sort of sys.path adjustments to your scripts like in this answer or install your packages to your system package repository where Jupyter Notebook is also looking for packages.

Upvotes: 1

Related Questions