Reputation: 341
First off I know this question has been asked 1000 times, but I cant seem to find an answer that works so sorry if this is a repeat, if you know a question that answers this please do share.
I've got the following directory structure:
my_app_dir
├── my_app
│ ├── __init__.py
│ ├── main.py
│ ├── services
│ │ ├── __init__.py
│ │ └── my_service.py
│ └── objects
└── testing
├── service_tests
│ ├── __init__.py
│ └── test_my_service.py
└── __init__.py
Im trying to import my_service from ./my_app_dir/my_app/services/my_service.py into my test case class test_my_service.py in ./my_app_dir/testing/service_tests/my_service.py
Im trying to import it in my module like so:
import unittest
from my_app.services.my_service import MyService
class MyTest(unittest.TestCase):
...
I get an error: cannot import module my_app...
the twist here is that im trying to run this in VS code with debugging. I have the following launch.json:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}"
}
]
}
I did try adding to the PYTHONPATH in the launch.json like this:
"env":{
"PYTHONPATH":"${PYTHONPATH}C:my_app_dir\\my_app"
}
This test code needs to be portable to other machines so I would really like to not have to modify the sys path.
Is there an issue with how im importing the module and or the directory structure im using?
Thanks!
Upvotes: 0
Views: 59
Reputation: 341
Simple question gets a simple answer. I was setting the PYTHONPATH incorrectly in the launch.json. I changed it to the following:
"env": {
"PYTHONPATH": "${workspaceRoot}"
}
Please correct me if this isn't the best way of doing this.
Upvotes: 0
Reputation: 629
I am not sure why modifying sys.path
would reduce portability:
# my_app_dir/testing/service_tests/my_service.py
import sys, os
initial_sys_path = sys.path.copy()
PATH_TO_MYAPPDIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
sys.path.append(PATH_TO_MYAPPDIR)
from my_app.services.my_service import MyService
# If you really want to clean sys.path afterwards
sys.path = initial_sys_path
However, there is also the possibility to use os.chdir
as suggested in https://stackoverflow.com/a/61326547/6068769:
PATH_TO_MYAPPDIR = .... # same as above
os.chdir(PATH_TO_MYAPPDIR)
from my_app.services.my_service import MyService
Finally, I am not a VS user, but for the PYTHONPATH solution, I think the variable should point to C:\my_app_dir
"env":{
"PYTHONPATH":"${PYTHONPATH}C:my_app_dir"
}
Upvotes: 1