Skip to content

Instantly share code, notes, and snippets.

@p-i-
Created August 8, 2024 12:00
Show Gist options
  • Save p-i-/6fa0171819b2647fa7ba0a6f0dc0efb4 to your computer and use it in GitHub Desktop.
Save p-i-/6fa0171819b2647fa7ba0a6f0dc0efb4 to your computer and use it in GitHub Desktop.
Getting imports from another folder to work in .ipynb in VSCode
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/Users/pi/code/2024/vscode_setup/nbs\n"
]
}
],
"source": [
"! pwd"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[01;34m..\u001b[0m\n",
"├── \u001b[01;34mnbs\u001b[0m\n",
"│   ├── \u001b[00mfix.png\u001b[0m\n",
"│   └── \u001b[00mx.ipynb\u001b[0m\n",
"└── \u001b[01;34mtools\u001b[0m\n",
" ├── \u001b[00m__init__.py\u001b[0m\n",
" ├── \u001b[00mother.py\u001b[0m\n",
" └── \u001b[00mtools.py\u001b[0m\n",
"\n",
"3 directories, 5 files\n"
]
}
],
"source": [
"! rm -rf ../tools/__pycache__/\n",
"! rm -rf ../.vscode/\n",
"\n",
"! tree ..\n",
"\n",
"# ⚡️ Restart VSCode here, so that we have a fresh testcase"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# 🔸 tools.py\n",
"print('tools.py loaded')\n",
"def f():\n",
" print(42)\n",
"\n",
"# 🔸 other.py\n",
"print('other.py loaded')\n",
"def g():\n",
" print('g')\n"
]
}
],
"source": [
"! cat ../tools/{tools,other}.py"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'ModuleNotFoundError'> No module named 'tools'\n"
]
}
],
"source": [
"# import sys\n",
"# sys.path.append('../tools') # 🟡 This works, but feels like \"cheating\"\n",
"\n",
"try:\n",
" from tools import f\n",
"except Exception as e:\n",
" print(type(e), e)\n",
"# ❌ ModuleNotFoundError: No module named 'tools'"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"! mkdir ../.vscode\n",
"\n",
"import json\n",
"J = {\n",
" \"jupyter.notebookFileRoot\": \"${workspaceFolder}/tools\",\n",
"}\n",
"\n",
"with open('../.vscode/settings.json', 'w') as f:\n",
" json.dump(J, f)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### ⚡️ Close and re-open .ipynb before continuing\n",
"\n",
"- Restarting the kernel is not sufficient.\n",
"- Close and re-open .ipynb IS sufficient.\n",
"- Restarting VSCode is overkill."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tools.py loaded\n",
"42\n"
]
}
],
"source": [
"from tools import f\n",
"f()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"other.py loaded\n"
]
}
],
"source": [
"\n",
"from other import g # 🟡 yellow-squiggly underline under `other`"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"g\n"
]
}
],
"source": [
"# There's a yellow squiggle under each `other`\n",
"# Hovering:\n",
"# > Import \"other\" could not be resolved (Pylance (reportMissingImports))\n",
"\n",
"# ... but we can still execute!\n",
"g()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# This doesn't do anything\n",
"if 0:\n",
" ! touch ../tools/__init__.py\n",
"\n",
" # ⚡️ Close and reopen .ipynb\n",
"\n",
" # 🫤 same issue\n",
"\n",
" ! echo 'from .other import g' > ../tools/__init__.py\n",
"\n",
" # ⚡️ Close and reopen .ipynb\n",
"\n",
" # 🫤 same issue"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# ⚡️ Apply the VSCode-suggested fix\n",
"\n",
"![fix.png](fix.png)\n",
"\n",
"... the squiggles go away"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"jupyter.notebookFileRoot\": \"${workspaceFolder}/tools\",\n",
" \"python.analysis.extraPaths\": [\n",
" \"./tools\"\n",
" ]\n",
"}"
]
}
],
"source": [
"! cat ../.vscode/settings.json"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Q: Why did `tools` work, but `other` required `.extraPaths`?\n",
"A: I think because `tools.py` matches the `tools/` containing folder name\n",
"\n",
"Q: Why did this addition to settings.json insta-fix, whereas the previous _creation_ of settings.json required a VSCode restart?\n",
"A: Maybe because .extraPaths is for PyLance, but `notebookFileRoot` is likely being read upon spawning the .ipynb viewer."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
@p-i-
Copy link
Author

p-i- commented Aug 8, 2024

fix.png

fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment