Skip to content

Instantly share code, notes, and snippets.

@paddymul
Created February 6, 2024 16:15
Show Gist options
  • Save paddymul/acffe2a902db7ad2cee1a7c223be7f88 to your computer and use it in GitHub Desktop.
Save paddymul/acffe2a902db7ad2cee1a7c223be7f88 to your computer and use it in GitHub Desktop.
Showing an attempt at making more sane stack traces from classes using traits heavily
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "54685928-3f8c-430e-b270-09e51949997f",
"metadata": {},
"source": [
"# Demo of the trait exception rewriting\n",
"\n",
"Traitlets results in very long stacktraces. Look at the difference between these two stack traces.\n",
"\n",
"Watch this space, These stacktraces still aren't great, but they are much better"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "3ba20b97-144d-459a-8217-f9e1793acbc7",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import sys\n",
"from traitlets import Unicode, Any, observe, HasTraits, Dict\n",
"import six"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "091125db-b117-4b92-b1d4-231c54a8b1ea",
"metadata": {
"tags": []
},
"outputs": [
{
"ename": "ZeroDivisionError",
"evalue": "division by zero",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[2], line 28\u001b[0m\n\u001b[1;32m 25\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcompute_second\u001b[39m(\u001b[38;5;28mself\u001b[39m, val):\n\u001b[1;32m 26\u001b[0m \u001b[38;5;241m1\u001b[39m\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m0\u001b[39m\n\u001b[0;32m---> 28\u001b[0m ErrorSecond(\u001b[38;5;241m5\u001b[39m)\n",
"Cell \u001b[0;32mIn[2], line 8\u001b[0m, in \u001b[0;36mDumbBase.__init__\u001b[0;34m(self, val)\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__init__\u001b[39m(\u001b[38;5;28mself\u001b[39m, val):\n\u001b[1;32m 7\u001b[0m \u001b[38;5;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__init__\u001b[39m()\n\u001b[0;32m----> 8\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfirst_trait \u001b[38;5;241m=\u001b[39m val\n",
"File \u001b[0;32m~/anaconda3/envs/buckaroo-dev-5/lib/python3.11/site-packages/traitlets/traitlets.py:729\u001b[0m, in \u001b[0;36mTraitType.__set__\u001b[0;34m(self, obj, value)\u001b[0m\n\u001b[1;32m 727\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m TraitError(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mThe \u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m trait is read-only.\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m%\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mname)\n\u001b[1;32m 728\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 729\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mset(obj, value)\n",
"File \u001b[0;32m~/anaconda3/envs/buckaroo-dev-5/lib/python3.11/site-packages/traitlets/traitlets.py:718\u001b[0m, in \u001b[0;36mTraitType.set\u001b[0;34m(self, obj, value)\u001b[0m\n\u001b[1;32m 714\u001b[0m silent \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[1;32m 715\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m silent \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[1;32m 716\u001b[0m \u001b[38;5;66;03m# we explicitly compare silent to True just in case the equality\u001b[39;00m\n\u001b[1;32m 717\u001b[0m \u001b[38;5;66;03m# comparison above returns something other than True/False\u001b[39;00m\n\u001b[0;32m--> 718\u001b[0m obj\u001b[38;5;241m.\u001b[39m_notify_trait(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mname, old_value, new_value)\n",
"File \u001b[0;32m~/anaconda3/envs/buckaroo-dev-5/lib/python3.11/site-packages/traitlets/traitlets.py:1503\u001b[0m, in \u001b[0;36mHasTraits._notify_trait\u001b[0;34m(self, name, old_value, new_value)\u001b[0m\n\u001b[1;32m 1500\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_notify_trait\u001b[39m(\u001b[38;5;28mself\u001b[39m, name, old_value, new_value):\n\u001b[1;32m 1501\u001b[0m \u001b[38;5;66;03m# print(\"name\", name, \"old_value\", old_value)\u001b[39;00m\n\u001b[1;32m 1502\u001b[0m \u001b[38;5;66;03m# try:\u001b[39;00m\n\u001b[0;32m-> 1503\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mnotify_change(\n\u001b[1;32m 1504\u001b[0m Bunch(\n\u001b[1;32m 1505\u001b[0m name\u001b[38;5;241m=\u001b[39mname,\n\u001b[1;32m 1506\u001b[0m old\u001b[38;5;241m=\u001b[39mold_value,\n\u001b[1;32m 1507\u001b[0m new\u001b[38;5;241m=\u001b[39mnew_value,\n\u001b[1;32m 1508\u001b[0m owner\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 1509\u001b[0m \u001b[38;5;28mtype\u001b[39m\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mchange\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 1510\u001b[0m )\n\u001b[1;32m 1511\u001b[0m )\n",
"File \u001b[0;32m~/anaconda3/envs/buckaroo-dev-5/lib/python3.11/site-packages/traitlets/traitlets.py:1519\u001b[0m, in \u001b[0;36mHasTraits.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m 1517\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mnotify_change\u001b[39m(\u001b[38;5;28mself\u001b[39m, change):\n\u001b[1;32m 1518\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Notify observers of a change event\"\"\"\u001b[39;00m\n\u001b[0;32m-> 1519\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_notify_observers(change)\n",
"File \u001b[0;32m~/anaconda3/envs/buckaroo-dev-5/lib/python3.11/site-packages/traitlets/traitlets.py:1566\u001b[0m, in \u001b[0;36mHasTraits._notify_observers\u001b[0;34m(self, event)\u001b[0m\n\u001b[1;32m 1563\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(c, EventHandler) \u001b[38;5;129;01mand\u001b[39;00m c\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 1564\u001b[0m c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, c\u001b[38;5;241m.\u001b[39mname)\n\u001b[0;32m-> 1566\u001b[0m c(event)\n",
"Cell \u001b[0;32mIn[2], line 15\u001b[0m, in \u001b[0;36mDumbBase.handle_first\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[38;5;129m@observe\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfirst_trait\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 14\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mhandle_first\u001b[39m(\u001b[38;5;28mself\u001b[39m, change):\n\u001b[0;32m---> 15\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msecond_trait \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcompute_first(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfirst_trait)\n",
"File \u001b[0;32m~/anaconda3/envs/buckaroo-dev-5/lib/python3.11/site-packages/traitlets/traitlets.py:729\u001b[0m, in \u001b[0;36mTraitType.__set__\u001b[0;34m(self, obj, value)\u001b[0m\n\u001b[1;32m 727\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m TraitError(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mThe \u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m trait is read-only.\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m%\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mname)\n\u001b[1;32m 728\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 729\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mset(obj, value)\n",
"File \u001b[0;32m~/anaconda3/envs/buckaroo-dev-5/lib/python3.11/site-packages/traitlets/traitlets.py:718\u001b[0m, in \u001b[0;36mTraitType.set\u001b[0;34m(self, obj, value)\u001b[0m\n\u001b[1;32m 714\u001b[0m silent \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[1;32m 715\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m silent \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[1;32m 716\u001b[0m \u001b[38;5;66;03m# we explicitly compare silent to True just in case the equality\u001b[39;00m\n\u001b[1;32m 717\u001b[0m \u001b[38;5;66;03m# comparison above returns something other than True/False\u001b[39;00m\n\u001b[0;32m--> 718\u001b[0m obj\u001b[38;5;241m.\u001b[39m_notify_trait(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mname, old_value, new_value)\n",
"File \u001b[0;32m~/anaconda3/envs/buckaroo-dev-5/lib/python3.11/site-packages/traitlets/traitlets.py:1503\u001b[0m, in \u001b[0;36mHasTraits._notify_trait\u001b[0;34m(self, name, old_value, new_value)\u001b[0m\n\u001b[1;32m 1500\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_notify_trait\u001b[39m(\u001b[38;5;28mself\u001b[39m, name, old_value, new_value):\n\u001b[1;32m 1501\u001b[0m \u001b[38;5;66;03m# print(\"name\", name, \"old_value\", old_value)\u001b[39;00m\n\u001b[1;32m 1502\u001b[0m \u001b[38;5;66;03m# try:\u001b[39;00m\n\u001b[0;32m-> 1503\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mnotify_change(\n\u001b[1;32m 1504\u001b[0m Bunch(\n\u001b[1;32m 1505\u001b[0m name\u001b[38;5;241m=\u001b[39mname,\n\u001b[1;32m 1506\u001b[0m old\u001b[38;5;241m=\u001b[39mold_value,\n\u001b[1;32m 1507\u001b[0m new\u001b[38;5;241m=\u001b[39mnew_value,\n\u001b[1;32m 1508\u001b[0m owner\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 1509\u001b[0m \u001b[38;5;28mtype\u001b[39m\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mchange\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 1510\u001b[0m )\n\u001b[1;32m 1511\u001b[0m )\n",
"File \u001b[0;32m~/anaconda3/envs/buckaroo-dev-5/lib/python3.11/site-packages/traitlets/traitlets.py:1519\u001b[0m, in \u001b[0;36mHasTraits.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m 1517\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mnotify_change\u001b[39m(\u001b[38;5;28mself\u001b[39m, change):\n\u001b[1;32m 1518\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Notify observers of a change event\"\"\"\u001b[39;00m\n\u001b[0;32m-> 1519\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_notify_observers(change)\n",
"File \u001b[0;32m~/anaconda3/envs/buckaroo-dev-5/lib/python3.11/site-packages/traitlets/traitlets.py:1566\u001b[0m, in \u001b[0;36mHasTraits._notify_observers\u001b[0;34m(self, event)\u001b[0m\n\u001b[1;32m 1563\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(c, EventHandler) \u001b[38;5;129;01mand\u001b[39;00m c\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 1564\u001b[0m c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, c\u001b[38;5;241m.\u001b[39mname)\n\u001b[0;32m-> 1566\u001b[0m c(event)\n",
"Cell \u001b[0;32mIn[2], line 22\u001b[0m, in \u001b[0;36mDumbBase.handle_second\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;129m@observe\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124msecond_trait\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 21\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mhandle_second\u001b[39m(\u001b[38;5;28mself\u001b[39m, change):\n\u001b[0;32m---> 22\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mthird_trait \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcompute_second(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msecond_trait)\n",
"Cell \u001b[0;32mIn[2], line 26\u001b[0m, in \u001b[0;36mErrorSecond.compute_second\u001b[0;34m(self, val)\u001b[0m\n\u001b[1;32m 25\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcompute_second\u001b[39m(\u001b[38;5;28mself\u001b[39m, val):\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;241m1\u001b[39m\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m0\u001b[39m\n",
"\u001b[0;31mZeroDivisionError\u001b[0m: division by zero"
]
}
],
"source": [
"class DumbBase(HasTraits):\n",
" first_trait = Any()\n",
" second_trait = Any()\n",
" third_trait = Any()\n",
"\n",
" def __init__(self, val):\n",
" super().__init__()\n",
" self.first_trait = val\n",
" \n",
" def compute_first(self, val):\n",
" return val\n",
" \n",
" @observe('first_trait')\n",
" def handle_first(self, change):\n",
" self.second_trait = self.compute_first(self.first_trait)\n",
"\n",
" def compute_second(self, val):\n",
" return val\n",
" \n",
" @observe('second_trait')\n",
" def handle_second(self, change):\n",
" self.third_trait = self.compute_second(self.second_trait)\n",
"\n",
"class ErrorSecond(DumbBase):\n",
" def compute_second(self, val):\n",
" 1/0\n",
" \n",
"ErrorSecond(5)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "1876620c-eb2c-4bdc-8a90-761c51a9a77b",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"self.exception (<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero'), <traceback object at 0x106fb5880>)\n"
]
},
{
"ename": "ZeroDivisionError",
"evalue": "division by zero",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[4], line 50\u001b[0m\n\u001b[1;32m 48\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcompute_second\u001b[39m(\u001b[38;5;28mself\u001b[39m, val):\n\u001b[1;32m 49\u001b[0m \u001b[38;5;241m1\u001b[39m\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m0\u001b[39m\n\u001b[0;32m---> 50\u001b[0m ab \u001b[38;5;241m=\u001b[39m ErrorSecondSmart(\u001b[38;5;241m5\u001b[39m)\n\u001b[1;32m 51\u001b[0m ab\n",
"Cell \u001b[0;32mIn[4], line 25\u001b[0m, in \u001b[0;36mSmartBase.__init__\u001b[0;34m(self, val)\u001b[0m\n\u001b[1;32m 23\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mself.exception\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mexception)\n\u001b[1;32m 24\u001b[0m exc, exc1, tb \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mexception\n\u001b[0;32m---> 25\u001b[0m six\u001b[38;5;241m.\u001b[39mreraise(exc, exc1, tb)\n",
"File \u001b[0;32m~/anaconda3/envs/buckaroo-dev-5/lib/python3.11/site-packages/six.py:718\u001b[0m, in \u001b[0;36mreraise\u001b[0;34m(tp, value, tb)\u001b[0m\n\u001b[1;32m 716\u001b[0m value \u001b[38;5;241m=\u001b[39m tp()\n\u001b[1;32m 717\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m value\u001b[38;5;241m.\u001b[39m__traceback__ \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m tb:\n\u001b[0;32m--> 718\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m value\u001b[38;5;241m.\u001b[39mwith_traceback(tb)\n\u001b[1;32m 719\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m value\n\u001b[1;32m 720\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n",
"Cell \u001b[0;32mIn[4], line 42\u001b[0m, in \u001b[0;36mSmartBase.handle_second\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m 38\u001b[0m \u001b[38;5;129m@observe\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124msecond_trait\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 39\u001b[0m \u001b[38;5;129m@exception_protect\u001b[39m\n\u001b[1;32m 40\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mhandle_second\u001b[39m(\u001b[38;5;28mself\u001b[39m, change):\n\u001b[1;32m 41\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 42\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mthird_trait \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcompute_second(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msecond_trait)\n\u001b[1;32m 43\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 44\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mexception \u001b[38;5;241m=\u001b[39m sys\u001b[38;5;241m.\u001b[39mexc_info()\n",
"Cell \u001b[0;32mIn[4], line 49\u001b[0m, in \u001b[0;36mErrorSecondSmart.compute_second\u001b[0;34m(self, val)\u001b[0m\n\u001b[1;32m 48\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcompute_second\u001b[39m(\u001b[38;5;28mself\u001b[39m, val):\n\u001b[0;32m---> 49\u001b[0m \u001b[38;5;241m1\u001b[39m\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m0\u001b[39m\n",
"\u001b[0;31mZeroDivisionError\u001b[0m: division by zero"
]
}
],
"source": [
"def exception_protect(func):\n",
" def wrapped(self, *args, **kwargs):\n",
" try:\n",
" func(self, *args, **kwargs)\n",
" except Exception as e:\n",
" if self.exception is None:\n",
" self.exception = sys.exc_info()\n",
" raise\n",
" return wrapped\n",
"\n",
"class SmartBase(HasTraits):\n",
" first_trait = Any()\n",
" second_trait = Any()\n",
" third_trait = Any()\n",
"\n",
" def __init__(self, val):\n",
" super().__init__()\n",
" self.exception = None\n",
" try:\n",
" self.first_trait = val\n",
" except Exception as e:\n",
" # print(\"e\", sys.exc_info())\n",
" print(\"self.exception\", self.exception)\n",
" exc, exc1, tb = self.exception\n",
" six.reraise(exc, exc1, tb)\n",
" \n",
" def compute_first(self, val):\n",
" return val\n",
" \n",
" @observe('first_trait')\n",
" @exception_protect\n",
" def handle_first(self, change):\n",
" self.second_trait = self.compute_first(self.first_trait)\n",
"\n",
" def compute_second(self, val):\n",
" return val\n",
" \n",
" @observe('second_trait')\n",
" @exception_protect\n",
" def handle_second(self, change):\n",
" try:\n",
" self.third_trait = self.compute_second(self.second_trait)\n",
" except Exception as e:\n",
" self.exception = sys.exc_info()\n",
" raise\n",
"\n",
"class ErrorSecondSmart(SmartBase):\n",
" def compute_second(self, val):\n",
" 1/0\n",
"ab = ErrorSecondSmart(5)\n",
"ab"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "48b4e65c-8ac9-487b-9e9e-7cb5e9dd4fb1",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.11.7"
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {},
"version_major": 2,
"version_minor": 0
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment