Python nested import 'ModuleNotFound' error - python

I have the following folder structure:
high_level.py (top level)
low_level (directory)
low_level_script.py (within 'low_level')
config.py (within 'low_level')
And the following code:
high_level.py
from low_level import low_level_script
low_level_script.test_fun()
low_level_script.py
import config
def test_fun():
return config.A
config.py
A = 1
If I do the following, at the top level, I get an import error.
import high_level
ModuleNotFoundError: No module named 'config'
Why is this, and what is the best way of making the script.py able to import config.py, in a way that makes script.py importable from its own directory, and the directory above?
The reason why I'm interested in this is because I want to have a pytest tests in test_high_level.py, and test_low_level.py pytest script that import the high-level and low-level scripts.
I'm using Python 3.7. I see another question asking something similar here, but there doesn't seem to be a concrete suggestion, except reading all of this documentation.
Nested Python module imports
https://docs.python.org/3/reference/import.html
This question also seems similar - it recommends using libname, but I'm not completely sure how this addresses the problem.
Python: ModuleNotFound Error

To use relative imports you should precede the module name with a dot.
import .config
or use absolute imports instead
from low_level import config

Related

Python module import error without using sys module

I am trying to use my own custom module, but It is unable to load the module.
This is a hierarchy structure of my custom module.
sources\
set1\
module_1
module_2
set2\
module_3
set3\
module_4
I imported these modules like below
from sources.set1.module_1 import *
from sources.set2.module_2 import method
...
And it occurs import error.
The error message is No module named 'sources
I use VScode, and Python 3.7 (I expect that I don't need to use init.py)
I've googled this problem and I've found 2 solutions. However, these weren't helpful.
Using sys.path.append()
This couldn't be a solution for me. Because I am working with teammates, and it is not allowed to add this code just for me
Adding PYTHONPATH environment variable
I've already added PYTHONPATH with "C://directories//sources",but it doesn't soleve import error. However, I found that this solution allows below codes instead of the original codes.
import module_1 #This occurs no error, But I can't use it
...
You have to call as a packages, for that you have to use init,py in each subdirectory https://www.learnpython.org/en/Modules_and_Packages

AWS Lambda: Unable to import module 'package/file': No module named 'util'

I am struggling to get module importing to work in AWS lambda using Python 3.
My file structure looks like this:
package:
stage1.py
__init__.py
util:
helper1.py
__init__.py
helper1.py is a simple util class:
def foo():
print("yes")
Within stage1.py I have the following lines that cause Lambda to throw an error when it is starting:
from util.helper1 import foo
foo()
Unable to import module 'package/stage1': No module named 'util'
Both __init__.py files are empty.
Sadly, I see that this works if I invoke the script locally. Frustrating is an understatement!
Thanks to some of the links sent above and my own (and necessary) research into how imports are handled in python, I figured out the issue regarding unavailable modules.
How I debugged my app in Lambda:
I attached this line of code to the top of the file
print("Name is ({})".format(__name__))
This gave me an output that could help me understand an make an educated decision on how to import the files in the util module. I saw an output for the stage1.py file was packager/stage1. This made the import code modifications easy to make.
I changed the imports in the stage1.py file to (using absolute path imports -- pep recommendation):
from packager.util.helper1 import foo
For whatever subjective reason, this link helped me understand the process the most.
I avoided this issue using a leading dot in the path like this
# package.py
from .util.helper1 import foo

Python - fails importing package

I have trouble importing package.
My file structure is like this:
filelib/
__init__.py
converters/
__init__.py
cmp2locus.py
modelmaker/
__init__.py
command_file.py
In module command_file.py I have a class named CommandFile which i want to call in the cmp2locus.py module.
I have tried the following in cmp2locus.py module:
import filelib.modelmaker.command_file
import modelmaker.command_file
from filelib.modelmaker.command_file import CommandFile
All these options return ImportError: No modules named ...
Appreciate any hint on solving this. I do not understand why this import does not work.
To perform these imports you have 3 options, I'll list them in the order I'd prefer. (For all of these options I will be assuming python 3)
Relative imports
Your file structure looks like a proper package file structure so this should work however anyone else trying this option should note that it requires you to be in a package; this won't work for some random script.
You'll also need to run the script doing the importing from outside the package, for example by importing it and running it from there rather than just running the cmp2locus.py script directly
Then you'll need to change your imports to be relative by using ..
So:
import filelib.modelmaker.command_file
becomes
from ..modelmaker import command_file
The .. refers to the parent folder (like the hidden file in file systems).
Also note you have to use the from import syntax because names starting with .. aren't valid identifiers in python. However you can of course import it as whatever you'd like using from import as.
See also the PEP
Absolute imports
If you place your package in site-packages (the directories returned by site.getsitepackages()) you will be able to use the format of imports that you were trying to use in the question. Note that this requires any users of your package to install it there too so this isn't ideal (although they probably would, relying on it is bad).
Modifying the python path
As Meera answered you can also directly modify the python path by using sys.
I dislike this option personally as it feels very 'hacky' but I've been told it can be useful as it gives you precise control of what you can import.
To import from another folder, you have to append that path of the folder to sys.path:
import sys
sys.path.append('path/filelib/modelmaker')
import command_file

Importing a python standard library with the same name as the current module

I'm trying to build a Python project, and the name of the current module (lets call it email) is the same name as a module in the standard library. I need to import from the standard library, but I am getting an error with trying to import from the library.
Example:
Project/
email.py
# email.py script
import email
# do something with the standard email library.
Is there any way I can still keep the name of my module email.py, or is the best option changing it? I have done some research, and they seem to relate more to having a case like this:
Project/
main.py # Current module
email.py
First, it is bad practice to create a module that shadows another module. However, that doesn't prevent you from proceeding.
Import __future__ import absolute_import as your first import in your main file.
This forces imports to use absolute paths instead of relative. Now, import email imports that standard library. You can import your local version by from . import email
Your best option is to change your own module's name. Conflicting names are always terrible in Python!
One time I crashed IDLE and my python just because I had a file called code.py

Multilevel relative import

Multilevel relative import
I have following folder structure
top\
__init__.py
util\
__init__.py
utiltest.py
foo\
__init__.py
foo.py
bar\
__init__.py
foobar.py
I want to access from foobar.py the module utiltest.py. I tried following relative import, but this doesn't work:
from ...util.utiltest import *
I always get
ValueError: Attempted relative import beyond toplevel package
How to do such a multileve relative import?
I realize this is an old question, but I feel the accepted answer likely misses the main issue with the questioner's code. It's not wrong, strictly speaking, but it gives a suggestion that only coincidentally happens to work around the real issue.
That real issue is that the foobar.py file in top\foo\bar is being run as a script. When a (correct!) relative import is attempted, it fails because the Python interpreter doesn't understand the package structure.
The best fix for this is to run foobar.py not by filename, but instead to use the -m flag to the interpreter to tell it to run the top.foo.bar.foobar module. This way Python will know the main module it's loading is in a package, and it will know exactly where the relative import is referring.
You must import foobar from the parent folder of top:
import top.foo.bar.foobar
This tells Python that top is the top level package. Relative imports are possible only inside a package.

Categories

Resources