I have the common problem of the "module not found" error when trying to import a file within a folder in my project directory as a package. I've tried several solutions from Stackoverflow answers, but none are working for me. Here's what's going on, and what I've tried:
I'm working in a conda environment devenv on a Flask project, using PyCharm, and have a project directory like this:
/some/path/project_root/
migrations/
static/
templates/
reporting/
__init__.py
code.py
tests.py
Inside the tests.py file there are import statements to import code.py as a module:
from .code import my_function
However, when I run (devenv) me#comp:project_root$ > python reporting/tests.py
I get the error: ModuleNotFoundError: No module named '__main__.code'; '__main__' is not a package
I tried appending the project directory path to $PYTHONPATH, and echo $PYTHONPATH returns /some/path/project_root/
What do I need to configure to get this to work properly? Also, whatever settings I need to change, can I make those settings specific to the development environment I'm using?
Change from .code import my_function to from code import my_function. The top level of a package is defined by the highest folder with an __init__.py file. So the top level of your project is the reporting folder and code.py does not need to be a relative import. Best to either avoid relative imports or get an editor like PyCharm that will take care of it for you!
Related
My project file structure is like this,
project/src/test/myscript.py
project/src/utils/file_utils.py
When I run myscript.py, which has from utils import file_utils, it gave me error:
ModuleNotFoundError: No module named 'utils'
Previously in Pycharm IDE I did not get this type of error (maybe due to _ init _.py), the subdirs of the same parent dir could be detected. But not sure for VSCode, is there something I need to add for specifying the file structure? And I opened the folder project as my VSCode workspace (not sure if where I open the workspace matters)
I tried adding:
in the /project/.vscode/launch.json
"cwd": "${workspaceFolder}/src"
or in the begining of myscript.py
import sys
import os
src_path = os.path.dirname(os.path.abspath('/project/src/'))
sys.path.insert(0, src_path)
But none of them works. Does anyone have any insights? Thank you very much!
You could consider placing a .env file at the root of your project which adds your source directory to PYTHONPATH. i.e. something like
>>> cat /project/.env
PYTHONPATH=/project/src/
>>>
Your code will look a smidgen nicer without the explicit manipulation of sys.path.
VSCode's usage of .env files is documented here.
Yes, in Pycharm you didn't get this error because it adds __init__.py file automatically when you create a python module. The python identifies the structure of your project through these files, if your folder does not have __init__.py python will understand it as just any folder.
Unlike pycharm, vscode uses the workspace as the root directory to retrieve files. The first method you try is to write it in the launch.json file, which is applicable to debug rather than running it directly. You can use the following code to import:
from src.utils import file_utils
I am struggling with import issues with Python. I am working in a mono repo setting, where other directories are not related to python. Following is the structure of the directory.
monorepo
services
app1
app2
__init__.py
src
__init__.py
api
__init__.py
foo1.py
foo2.py
app3
I want to use the import structure of from app2.api.foo1 import Foo1 in foo2.py script.
In both cases, it fails. I see the path to app2 in the sys.path but still python does not see this as a module.
To export the path: I tried.
PYTHONPATH="${PYTHONPATH}:$(realpath $(pwd))" at terminal and
sys.path.append(full_path_app2) at console level. Still get the import error.
Any help on how to solve this?
Python imports can be tricky.
Python will look for importable modules inside the PythonPath (sys.path).
Importable modules are subfolders of any location in the path which contain a __init__.py file.
If you call a script file directly python script.py the directoy containing that file is added to the path automatically. If you use the module syntax python -m mymodule it will search the PYTHONPATH and execute the first module with the name mymodule.
In order to import app2, you need to add monorepo/services to the PythonPath. This should also allow you to directly import files in app2, i.e. from app2 import xyz.
If you are working with monorepos, you need to add all folders which may contain python modules to the path. I would recommend doing it using the environment variable PYTHONPATH instead of modifying sys.path programmatically.
So here is my problem.
I have a personal project on Python that I was usually running on PyCharm that I preferred to then switch to VSCode. But now, I have errors on file imports that I don't understand. I don't remember having modified something around the imports, I don't exactly know if it's something to do with the IDE or if it's a global problem.
So basically on the root of my project file, I have a "utils.py" file that I made to store functions I thought I would need to use frequently over my project. At the same location (project root), there's the main .py file that I launch.
I added the path of the utils.py file to my PYTHONPATH environment variables and when I search in the variable sys.path on my Python IDLE, it does actually show me my project root path.
My main.py also manages to correctly get that import.
However, on the project root, I have a folder with Python subfiles in it which cannot access that file.
So like, there's at the root main.py, utils.py and folder/subfile.py
On both main.py and the subfile.py, I added "from utils import *" to add the utils import that is recognised
On the main.py, the line doesn't show any error
On the subfile.py (in the folder), the line has the error "Unable to import 'utils' pylint(import-error)"
TLDR:
I have my project root folder with utils.py, main.py, folder/subfile.py
utils.py is on my PYTHONPATH environment variable
the utils.py import works on main.py
the utils.py import doesn't work on the subfile.py in the subfolder
(I don't know if it is due to the IDE or not)
If I'm understanding this correctly the subfile.py script is in another directory so you can't import the same way as you do in main.py you would need to do something similar to this answer so like
from ..utils import *
I'm trying to import a class in a different directory to another file, but can't seem to get it to work. I know this question has been asked a lot and I have looked through multiple stackoverflow solutions and at https://docs.python.org/3/tutorial/modules.html#packages
1: Importing files from different folder
2: import python file in another directory failed
I want to try to just use the method containing just __init__.py file instead of doing an import sys
My directory structure is as follows:
django_vue/
__init__.py
devices/
__init__.py
models.py
lib/
__init__.py
my_file.py
I'm trying to import the class Device from /django_vue/devices/models.py to /django_vue/lib/my_file.py by:
from devices.models import Device
However when I do that I still get the error:
from devices.models import Device
ModuleNotFoundError: No module named 'devices'
I'm not sure what I'm dong wrong since I already have the __init__ file in both directories. Any help is appreciated. Also I'm running python 3.6.
This is the folder structure I'm working with.
.
└── django_vue
├── devices
│ └── models.py
└── lib
└── file.py
When you run
$ python file.py
python has no way of knowing what's outside the directory.
python can't go back and then into devices/ just like that.
The easiest way to solve this would be to add the folder devices/ to sys.path. When python imports a module, it searches for the module from sys.path. Adding the path to devices/ would make it available for imports.
Here are my files.
# models.py
Device = 'device'
# file.py
import sys
sys.path.append('..') # adds the parent dir (which is django-vue/) to path
# django-vue dir has devices/ so now this is available for imports
# importing this works now
from devices.models import Device
print(Device)
Output
django_vue/lib$ python3 file.py
device
Think about it your are inside my_file.py and import something called devices.
How can python know where the name devices has come from.
It won't search your entire Drive for that module/package
Relative Import
use a relative import instead. write from ..devices.models import Device. This is telling python to go up one directory to the parent directory and that's where it will find the devices package. Your lib module should now work as a module
If you however run the my_file.py package directly (as in python C:/django_vue/lib/my_file.py)
You will still get an error. Not the same error; the new error will be something like
ImportError: attempted relative import with no known parent package
This is happening because you are actually running my_file.py
If you think about it why would you want to run my_file.py by itself when it is clearly a part of a package. Maybe you are just testing to see if the import works when you use your package. The problem with this is that it makes it seem like your packages relative imports don't work even though this actually works.
Create a main.py in django_vue and write from lib import my_file. This will run your my_file.py and you will notice there is no error.
What's happening here
Have you heard of __package__?
if you put print(str(__package__)) in your my_file.py and run my_file.py directly you will see that it prints None.
However if you run main.py (that you just created) you will see that when It reaches my_file.py, __package__ will actually be defined to something.
Ahhh... you see now it all makes sense; The error you originally got said something about no known parent package. If __package__ is undefined that means there is no relative parent package because the file was obviously run directly instead of as part of a package.
Consider Absolute imports
you also might want to consider using absolute imports because if you are working on the package you might change it directory structure while developing. so you need to keep changing the import references on the affected files.
Although you can find IDE's with python extensions that automatically to this as you change your directory. I believe VS Code does this automatically.
Replace the __init__ files with __main__.
SUMMARY
I am fairly new to designing full-fledged python projects, and all my Python work earlier has been with Jupyter Notebooks. Now that I am designing some application with Python, I am having considerable difficulty making it 'run'.
I have visited the following sites -
Relative imports in Python
Ultimate answer to relative python imports
python relative import example code does not work
But none of them seem to solve my issue.
PROBLEM
Here's my repo structure -
my_app/
__init__.py
code/
__init__.py
module_1/
some_code_1.py
module_2/
some_code_2.py
module_3/
some_code_3.py
main.py
tests/
__init__.py
module_1/
test_some_code_1.py
module_2/
test_some_code_2.py
module_3/
test_some_code_3.py
resources/
__init__.py
config.json
data.csv
I am primarily using PyCharm and VS Code for development and testing.
The main.py file has the following imports -
from code.module_1.some_code_1 import class_1
from code.module_2.some_code_2 import class_2
from code.module_3.some_code_3 import class_3
In the PyCharm run configuration, I have the working directory set to `User/blah/blah/my_app/
Whenever I run the main.py from PyCharm, it runs perfectly.
But if I run the program from terminal like -
$ python code/main.py
Traceback (most recent call last):
File "code/main.py", line 5, in <module>
from code.module_1.some_code_1 import class_1
ModuleNotFoundError: No module named 'code.module_1.some_code_1'; 'code' is not a package
I get the same error if I run the main.py from VS Code.
Is there a way to make this work for PyCharm as well as terminal?
If I change the imports to -
from module_1.some_code_1 import class_1
from module_2.some_code_2 import class_2
from module_3.some_code_3 import class_3
This works on the terminal but doesn't work in PyCharm. The test cases fail too.
Is there something I am missing, or some configuration that can be done to make all this work seamlessly?
Can someone help me with this?
Thanks!
The problem is when you do python code/main.py it makes your current working directory code/, which makes all of your absolute imports incorrect since Python doesn't see above that directory unless you explicitly change a setting like the PYTHONPATH environment variable.
Your best option is to rename main.py to __main__.py and then use python -m code (although do note that package name clashes with a module in the stdlib).
You also don't need the __init__.py in my_app/ unless you're going to treat that entire directory as a package.
And I would consider using relative imports instead of absolute ones (and I would also advise importing to the module and not the object/class in a module in your import statements to avoid circular import issues). For instance, for the from code.module_1.some_code_1 import class_1 line in code.main, I would make it from .module_1 import some_code_1.