I answered my own question, see solution below. Leaving this all here for posterity since I did quite a lot that others had said would work and had worked for them, yet none of it worked.
Problem
Below is a very simple python file. When trying to use Visual Studio Code's debugger on this file, I always get an ImportError
on any internal module, like app.models
or app.tests.scripts.stubs
. If those modules are listed below faker
, or any other external module, the debugger will go past the external module without throwing an error, but will throw an error on app.models
or whatever internal module is listed first. This is true in the 8-10 files I've tried this in.
What I've tried
I've specified the exact pythonPath in both launch.json and User Settings, as below. I've added "exceptionHandling"
to ignore ImportErrors. I've uninstalled and reinstalled Don Jayamanne's excellent Python extension. I've ran the Python: Select Workspace Interpreter
and pointed it to ./.venv/bin/python2.7
, ./.venv/bin/python2
, and ``./.venv/bin/python`.
Files
launch.json Python configuration
"name": "Python",
"type": "python",
"request": "launch",
"stopOnEntry": false,
"pythonPath": "/Users/REDACTED/REDACTED/.venv/bin/python2.7",
"program": "${file}",
"cwd": "${workspaceRoot}",
"env": null,
# we have 10+ environmental shell scripts, so I can't really use "envFile" in
# a meaningful way, though I have tried pointing it at one of the shell scripts
# but was still unable to debug.
"envFile": "${workspaceRoot}/.venv",
"debugOptions": [
"WaitOnAbnormalExit",
"WaitOnNormalExit",
"RedirectOutput"
],
"exceptionHandling": {
"ignore": [
"ImportError"
]
}
},
Python File
from app.models import Kelly
import app.tests.scripts.stubs
from faker import Faker
import factory
from datetime import datetime
from bson.objectid import ObjectId
fake = Faker()
kelly_names = [REDACTED]
class KellyFactory(factory.Factory):
class Meta:
model = Kelly
id = ObjectId()
is_archived = False
email = factory.LazyAttribute(
lambda kel: '%[email protected]' % kel.name.split()[0])
name = fake.word(ext_word_list=kelly_names)
phone = fake.phone_number()
date_last_modified = datetime.now()
kelly = KellyFactory()