Sign Up

Have an account? Sign In Now

Sign In

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have a permission to ask a question, You must login to ask question.

Forgot Password?

Need An Account, Sign Up Here
Sign InSign Up

ErrorCorner

ErrorCorner Logo ErrorCorner Logo

ErrorCorner Navigation

  • Home
  • Contact Us
  • About Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Contact Us
  • About Us
Home/ Questions/Q 596
Next
Answered
Kenil Vasani
Kenil Vasani

Kenil Vasani

  • 646 Questions
  • 567 Answers
  • 77 Best Answers
  • 26 Points
View Profile
  • 8
Kenil Vasani
Asked: December 14, 20202020-12-14T21:06:31+00:00 2020-12-14T21:06:31+00:00In: Python

Python: ‘ModuleNotFoundError’ when trying to import module from imported package

  • 8

I’m using Python 3.7.1 on macOS Mojave Version 10.14.1

This is my directory structure:

man/                          
  Mans/                  
          man1.py
  MansTest/
          SoftLib/
                  Soft/
                      SoftWork/
                              manModules.py
          Unittests/
                    man1test.py

man1.py contains the following import statement, which I do not want to change:

from Soft.SoftWork.manModules import *

man1test.py contains the following import statements:

from ...MansTest.SoftLib import Soft
from ...Mans import man1

I need the second import in man1test.py because man1test.py needs access to a function in man1.py.

My rationale behind the first import (Soft) was to facilitate the aforementioned import statement in man1.py.

Contrary to my expectation, however, the import statement in man1.py gives rise to:

ModuleNotFoundError: No module named 'Soft'

when I run

python3 -m man.MansTest.Unittests.man1test

from a directory above man/.

Is there any way to resolve this error without changing the import statement in man1.py and without adding anything to sys.path?

Edit: python3 -m man.ManTest.Unittests.man1test from the original version of the question changed to python3 -m man.MansTest.Unittests.man1test

pythonpython-3.xpython-import
  • 1 1 Answer
  • 11 Views
  • 0 Followers
  • 0
Answer
Share
  • Facebook

    1 Answer

    • Voted
    1. Kenil Vasani

      Kenil Vasani

      • 646 Questions
      • 567 Answers
      • 77 Best Answers
      • 26 Points
      View Profile
      Best Answer
      Kenil Vasani
      2020-12-14T21:02:23+00:00Added an answer on December 14, 2020 at 9:02 pm

      FIRST, if you want to be able to access man1.py from man1test.py AND manModules.py from man1.py, you need to properly setup your files as packages and modules.

      Packages are a way of structuring Python’s module namespace by using
      “dotted module names”. For example, the module name A.B designates a
      submodule named B in a package named A.

      …

      When importing the package, Python searches through the directories on
      sys.path looking for the package subdirectory.

      The __init__.py files are required to make Python treat the
      directories as containing packages; this is done to prevent
      directories with a common name, such as string, from unintentionally
      hiding valid modules that occur later on the module search path.

      You need to set it up to something like this:

      man
      |- __init__.py
      |- Mans
         |- __init__.py
         |- man1.py
      |- MansTest
         |- __init.__.py
         |- SoftLib
            |- Soft
               |- __init__.py
               |- SoftWork
                  |- __init__.py
                  |- manModules.py
            |- Unittests
               |- __init__.py
               |- man1test.py
      

      SECOND, for the “ModuleNotFoundError: No module named 'Soft'” error caused by from ...Mans import man1 in man1test.py, the documented solution to that is to add man1.py to sys.path since Mans is outside the MansTest package. See The Module Search Path from the Python documentation. But if you don’t want to modify sys.path directly, you can also modify PYTHONPATH:

      sys.path is initialized from these locations:

      • The directory containing the input script (or the current directory when no file is specified).
      • PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
      • The installation-dependent default.

      THIRD, for from ...MansTest.SoftLib import Soft which you said “was to facilitate the aforementioned import statement in man1.py“, that’s now how imports work. If you want to import Soft.SoftLib in man1.py, you have to setup man1.py to find Soft.SoftLib and import it there directly.

      With that said, here’s how I got it to work.

      man1.py:

      from Soft.SoftWork.manModules import *
      # no change to import statement but need to add Soft to PYTHONPATH
      
      def foo():
          print("called foo in man1.py")
          print("foo call module1 from manModules: " + module1())
      

      man1test.py

      # no need for "from ...MansTest.SoftLib import Soft" to facilitate importing..
      from ...Mans import man1
      
      man1.foo()
      

      manModules.py

      def module1():
          return "module1 in manModules"
      

      Terminal output:

      $ python3 -m man.MansTest.Unittests.man1test
      Traceback (most recent call last):
        ...
          from ...Mans import man1
        File "/temp/man/Mans/man1.py", line 2, in <module>
          from Soft.SoftWork.manModules import *
      ModuleNotFoundError: No module named 'Soft'
      
      $ PYTHONPATH=$PYTHONPATH:/temp/man/MansTest/SoftLib
      $ export PYTHONPATH
      $ echo $PYTHONPATH
      :/temp/man/MansTest/SoftLib
      $ python3 -m man.MansTest.Unittests.man1test
      called foo in man1.py
      foo called module1 from manModules: module1 in manModules 
      

      As a suggestion, maybe re-think the purpose of those SoftLib files. Is it some sort of “bridge” between man1.py and man1test.py? The way your files are setup right now, I don’t think it’s going to work as you expect it to be. Also, it’s a bit confusing for the code-under-test (man1.py) to be importing stuff from under the test folder (MansTest).

      • 6
      • Share
        Share
        • Share on Facebook
        • Share on Twitter
        • Share on LinkedIn
        • Share on WhatsApp

    You must login to add an answer.

    Forgot Password?

    Sidebar

    Ask A Question
    • Popular
    • Kenil Vasani

      SyntaxError: invalid syntax to repo init in the AOSP code

      • 5 Answers
    • Kenil Vasani

      runtimeError: package fails to pass a sanity check for numpy ...

      • 3 Answers
    • Kenil Vasani

      xlrd.biffh.XLRDError: Excel xlsx file; not supported

      • 3 Answers
    • Kenil Vasani

      Homebrew fails on MacOS Big Sur

      • 3 Answers
    • Kenil Vasani

      SQLSTATE[HY000]: General error: 1835 Malformed communication packet on LARAVEL

      • 2 Answers

    Explore

    • Most Answered
    • Most Visited
    • Most Voted
    • Random

    © 2020-2021 ErrorCorner. All Rights Reserved
    by ErrorCorner.com