Can't import module from local folder? "No module named" - python

I don't find the mistake in the code nor in the call when trying an import test.
My directory structure is the following: (from /home/user1/python_test/)
main.py
Aux/lib1.py
Aux/__init__.py
main.py:
from Aux.lib1 import fun_A
if __name__ == "__main__":
fun_A()
print("all done")
Aux/lib1.py:
def fun_A():
print("A function called")
I'm executing from terminal (python main.py from directory where main.py is), maybe is there a need to set pythonpath? I don't recall the need before, I've made some python programs like these some time ago (2/3 years)
I have also tried from .Aux.lib1 import fun_A instead of from Aux.lib1 import fun_A but nothing works. The error is:
File "main.py", line 1, in <module>
from Aux.lib1 import fun_A
ImportError: No module named Aux.lib1

Create a blank file with name __init__.py under the folder Aux. Without this file a directory can not be a module.

Oh my, It was a super silly mistake. I'm so used to execute inside a virtual environment that I was using python2 by mistake using python main.py. Executing python3 main.py worked for me.

Related

Subdirectory import giving error only when module gets imported from package

I've this package called classevivaAPI on PyPI (you can find it on GitHub here), of which I've for obvious reasons a git clone on my computer.
# main.py
from paths import paths
from variables.variables import *
In main.py I've the imports above, when main.py is the file marked as modified (with an M) below.
I'm testing this package with test.py, the gitignored file at the bottom of the screenshot, which has the following content:
#!\usr\bin\env python3
from classeviva import Session, Valutazioni, Note, Registro
from classeviva.variables import NoteSortBy
if __name__ == "__main__":
# Some code here
classeviva is the module included in the package classevivaAPI, and test.py is importing it via pip, I tested it and it gave me the same problem even if runned from a directory very far from src/ and in general src/classeviva.
When I ran it it gave me the following error:
Traceback (most recent call last):
File "d:\Python\Python\Classeviva\test.py", line 2, in <module>
from classeviva import Session, Valutazioni, Note, Registro
File "C:\Users\matti\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\classeviva\__init__.py", line 1, in <module>
from .main import *
File "C:\Users\matti\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\classeviva\main.py", line 3, in <module>
from paths import paths
ModuleNotFoundError: No module named 'paths'
I was quite confused since I had followed what explained here, here and expecially here.
So I had the idea to copy paste the if __name__ == '__main__' block of test.py at the bottom of main.py, and surprisingly it ran perfectly without giving me any error.
Does anybody know what is happening? Have you ever experienced this? Do you know how to fix it or what I'm doing wrong?
Edit
I searched for the module (classeviva) into the folder on my hard disk containing all the pip-installed modules, and I found it.
I opened its main.py, and the Visual Studio Code intellisense told me the same thing as CPython did before: there was no subfolder called path.
The setup.py file was missing the information about the submodules, I added them this way:
packages=[
'classeviva',
'classeviva.exceptions',
'classeviva.paths',
'classeviva.variables'
],
package_dir={
'': 'src',
'classeviva.exceptions': 'src/classeviva/exceptions',
'classeviva.paths': 'src/classeviva/paths',
'classeviva.variables': 'src/classeviva/variables',
},
I changed my main.py imports to the following:
# main.py
from .paths import paths
from .variables.variables import *
The .s were needed to access the subdirectories.
Now everything works fine.

How to write a package in Python with modules that reference each other?

I am trying to make a package with modules inside that import each other and I'm very confused on how it works. I made three files: test1.py, test2.py and __init__.py which are contained in my package directory testpack.
The contents of the files are as follows:
# test1.py
def demo():
print("123")
return
# test2.py
import test1
def demo2():
print("test 2")
test1.demo()
if __name__=="__main__":
demo2()
The __init__.py file is left empty. When I run test2.py on it's own I get the expected output:
test 2
123
I also have a main.py file in the parent directory of testpack
# main.py
import testpack.test1
import testpack.test2
testpack.test2.demo2()
Running this gives the error:
Traceback (most recent call last):
File "E:/packages/main.py", line 2, in <module>
import testpack.test2
File "E:\packages\testpack\test2.py", line 1, in <module>
import test1
ModuleNotFoundError: No module named 'test1'
Following some tips I tried running a different version of the code which yielded the same results:
# main.py alternative
from testpack.test2 import demo2
demo2()
What am I missing? My logic was that when importing testpack.test2 Python goes into test2.py where it has to import test1. Importing test1 shouldn't be an issue because we can successfully run test2.py on it's own, so it would construct demo2() using the function from test1, and I'd be all done, but I'm obviously wrong. At one point I thought that running import testpack.test1 before import testpack.test2 could be posing problems because I'd be importing test1 twice (once inside test2 also), but with the alternate version of main not running as well I'm completely lost.
SOLVED: As per MisterMiyagi's suggestion, the solution was to use from . import test1 instead of import test1 in test2.py. The dot specifies that the file to be imported is located in the same directory as the current file, a double dot would specify that the file to be imported is located in the parent directory, etc. I found this article to be helpful https://realpython.com/absolute-vs-relative-python-imports/

Importing From Another Script in Python

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!
Since you are importing the module from same directory you can simply import using.
from test import *
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.

Python Import file from sibling folder

I was trying to import a function from a sibling folder and i could, i look for documentation and didnt found something useful, can you help me please?
I have a folder named fold1, inside i have fold2 and fold3, inside fold2 i have filetoimport.py, it has:
def fntest(a, b):
return print(a+b)
And i want to import that function from inside fold3 file main.py, there i have
from fold2 import filetoimport
filetoimport.fntest(2,2)
Then i get an error:
Traceback (most recent call last):
File "fold3/main.py", line 1, in <module>
fold1 import filetoimport
ImportError: No module named 'fold1'
Hope you can help me :)
I also tried
from fold1.fold2 import filetoimport
But it failed.
Alright, this should work
import sys
import os
sys.path.insert(1,os.popen('pwd').read().replace('3\n','2'))
import filetoimport
filetoimport.fntest(2,2)
you just need to add the target folder to the python runtime path
You need to import the parent folder as a path the program can check inside for more modules. I had some luck with this
import os
import sys
sys.path.append(os.path.realpath('..'))
from fold2 import filetoimport
filetoimport.fntest(2,2)
As far as I have understood, your folder structure is as below
fold1
fold2
-- filetoimport.py
fold3
-- main.py
It seems that your are executing the main.py file from terminal (by opening fold1 path) as
python3 fold3/main.py
Instead you should execute the command as
python3 -m fold3.main
Since the argument is a module name, you must not give a file extension (.py)
On the other hand if you open fold1 as a project in IDE like pycharm or intellij idea and execute main.py via IDE itself, it wont give you an error.
Hope, this will solve your problem.

weird python3 import issue, No module named <module>

I write some python files like this:
main.py
view/ __init__.py #empity file
MainWindow.py
ListEditor.py
And in each file I wrote those imports:
<main.py>
from view.MainWindow import MainWindow
...
-
<MainWindow.py>
from view.ListEditor import ListEditor
and ListEditor.py don't import any files.
Each MainWindow.py or ListEditor.py defines a class that named same as the file name.
when I run the program from main.py, it works. But when I run from MainWindow.py I got ImportError: No module named 'view'
If I write
from ListEditor import ListEditor
in MainWindow.py, python MainWindow.py will be OK. but python main.py will get error:
ImportError: No module named 'ListEditor'
So, is there a way to make both python main.py and python MainWindow.py get right at the same time?
I'm using python3.4
P.S.
I think I have figured out the problem here. The import command searches a module in sys.path. The sys.path is a group of predefined paths plus the running script path. When I run the code from MainWindow.py, the code import ListEditor just works, but when I run from main.py, the current path is set to the parent path. So I need import view.ListEditor.
Well, there are couple ways to deal with it. #Vincent Beltman's answer is one of it. Or just put these code in the __init__.py file:
import os, sys
path = os.path.dirname(os.path.abspath(__file__))
sys.path.append(path)
Finally, I'm new to python. And I think the import command is quite strange. I thought it should search the files relative to the path of the source file that containing the command, not just relative to the starter file. A starter file may varying and cause troubles like this one.
Try this:
try:
from view.ListEditor import ListEditor # If this one fails
except:
try:
from ListEditor import ListEditor # It will try this one

Categories

Resources