VsCode provided venv creation feature. I tried it. Suppose, I have that project structure:
PJFOLDER
├── .venv/*
├── src/
│ └── inner_main.py
├── utils/
│ └── my_utils.py
└── outer_main.py
In both inner_main.py
and outer_main.py
I have imports of my_utils.py
like that:
from utils import my_utils
Python Interpreter selected correctly (even automatically), basic type checker enabled, no errors. When I run outer_main.py
via Ctrl+F5
or just Run Python file
- everything ok. But when I try to do the exact same thing with inner_main.py
it says ModuleNotFoundError: No module named 'my_utils'
.
I tried to type python -m src.inner_main
, with activated venv ofc, and it worked!
Well, I thought it is because PATH variable, indeed, it has path_to_project/PJFOLDER/.venv/Scripts/
but not my PJFOLDER
explicitly.
I tried this code:
import os
path_var = os.environ["PATH"].split(";")
path_var.insert(0, os.getcwd())
os.environ["PATH"] = ";".join(path_var)
But it didn't help.
Can someone clarify this situation for me, please? How am I supposed to run inner code with inner imports preferably using default VSCode features like debugger and Run Python file
? My project in early development and it can have multiple executable .py
files and I don't want to type\select everything in terminal...
UPD 1:
Based on @Michael Butscher comment. I've created file import_fix.py
with such code:
import sys
import os
sys.path.insert(0, os.getcwd())
This file lays in .venv
folder. Since sys.path
contains this folder, I can import it in any file in my project if I need. This file inserts current working directory in sys.path
and I can use imports. Though it seems odd. Why doesn't sys.path
contain cwd by default? Maybe there is a better solution? Maybe some setting in VSCode?
Well, there is 3 ways.
import_fix.py
file as I described above in UPD 1 and place it in .venv
folder. You can run your code or debug.launch.json
. {
"name": "Python Debugger: Module", // you can use whatever name you like
"type": "debugpy",
"request": "launch",
"module": "${command:extension.commandvariable.file.relativeFileDotsNoExtension}",
"justMyCode": false, // to debug my breakpoints
}
Select it. Press F5
or Ctrl+F5
to run the debugger. This extension provides correct module name relative to current working directory. If you manage to make it yourselves without third-party extension, please, let me know.
PJFOLDER/.venv/ANY-NON-EMPTY-NAME.pth
file with ../
content (or absolute/relative path to your PJFOLDER if you have different structure). This will include PJFOLDER in sys.path
despite you using virtual environment.First way is much simplier to create, but seems odd and you need to import unnecessary file whenever you need to import your code in others directories.
Second way is about debugging only. Though it's more convenient, strict, you don't need separate file to fix imports, you don't need that little overhead. If you want to run only, then you need to type python -m folders_separated_by_dots.module_name
. I belive, there is a way to create custom default command in VSCode to run file as module by default (maybe via tasks.json
...), but I'm not smart enough. Still, debugger is enough for me.
Third way is ... perfect? Default debugger works, Run Python file
works. Still, need to create this file and it's content and, I guess, VSCode should do this by default, but it's better than install VSCode extension and add new debugger configuration and forget about Run Python file
(though it's nothing crucial). So, I guess, that's the answer for me.
Though you can add useful info in comments.
UPD: 3rd way is not working with Python 3.12.2 when .pth
file has empty name, Read Security