|
28 | 28 | "outputs": [], |
29 | 29 | "source": [ |
30 | 30 | "#| export\n", |
31 | | - "import time,os,sys,traceback,contextlib,inspect,faulthandler,signal\n", |
| 31 | + "import time,os,sys,traceback,contextlib,inspect,faulthandler,signal,asyncio\n", |
32 | 32 | "from fastcore.basics import *\n", |
33 | 33 | "from fastcore.imports import *\n", |
34 | 34 | "from fastcore.foundation import *\n", |
|
53 | 53 | "outputs": [], |
54 | 54 | "source": [ |
55 | 55 | "#| export\n", |
56 | | - "def test_nb(\n", |
| 56 | + "async def test_nb(\n", |
57 | 57 | " fn, # file name of notebook to test\n", |
58 | 58 | " skip_flags=None, # list of flags marking cells to skip\n", |
59 | 59 | " force_flags=None, # list of flags marking cells to always run\n", |
|
89 | 89 | " if do_print: print(f'Starting {fn}')\n", |
90 | 90 | " try:\n", |
91 | 91 | " with working_directory(fn.parent):\n", |
92 | | - " k.run_all(nb, exc_stop=True, preproc=_no_eval, verbose=verbose)\n", |
| 92 | + " await k.run_all(nb, exc_stop=True, preproc=_no_eval, verbose=verbose)\n", |
93 | 93 | " if save: write_nb(nb, fn)\n", |
94 | 94 | " res = True\n", |
95 | 95 | " except: \n", |
|
102 | 102 | " else: os.environ['IN_TEST'] = prev_test\n" |
103 | 103 | ] |
104 | 104 | }, |
| 105 | + { |
| 106 | + "cell_type": "markdown", |
| 107 | + "id": "d7a14cc3", |
| 108 | + "metadata": {}, |
| 109 | + "source": [ |
| 110 | + "`test_nb` is async. `parallel` workers are fresh loopless processes, so each enters through `asyncio.run` at its process boundary, which keeps cells on the worker's main thread (where SIGALRM timeouts can arm). `run_sync` is reserved for sync callers already inside a running loop, like `exec_show_docs` under the sync processor pipeline.\n" |
| 111 | + ] |
| 112 | + }, |
| 113 | + { |
| 114 | + "cell_type": "code", |
| 115 | + "execution_count": null, |
| 116 | + "id": "12516e0a", |
| 117 | + "metadata": {}, |
| 118 | + "outputs": [], |
| 119 | + "source": [ |
| 120 | + "#| export\n", |
| 121 | + "def _test_nb_sync(fn, **kwargs): return asyncio.run(test_nb(fn, **kwargs))" |
| 122 | + ] |
| 123 | + }, |
105 | 124 | { |
106 | 125 | "cell_type": "markdown", |
107 | 126 | "id": "9dc26b80-6e4e-4a16-bcde-dd4d156289e5", |
|
118 | 137 | "outputs": [], |
119 | 138 | "source": [ |
120 | 139 | "_nb = Path('../../tests/directives.ipynb')\n", |
121 | | - "success,duration = test_nb(_nb, skip_flags=['notest'])\n", |
| 140 | + "success,duration = await test_nb(_nb, skip_flags=['notest'])\n", |
122 | 141 | "assert success" |
123 | 142 | ] |
124 | 143 | }, |
|
138 | 157 | "outputs": [], |
139 | 158 | "source": [ |
140 | 159 | "_nb = Path('../../tests/directives.ipynb')\n", |
141 | | - "success,duration = test_nb(_nb, showerr=False)\n", |
| 160 | + "success,duration = await test_nb(_nb, showerr=False)\n", |
142 | 161 | "assert not success" |
143 | 162 | ] |
144 | 163 | }, |
|
175 | 194 | " nbp = td/'prof.ipynb'\n", |
176 | 195 | " write_nb(new_nb([mk_cell('assert prof_x==7')]), nbp)\n", |
177 | 196 | " with modified_env(IPYTHONDIR=str(td)):\n", |
178 | | - " assert test_nb(nbp, showerr=False)[0]\n", |
179 | | - " assert not test_nb(nbp, showerr=False, profile=False)[0]" |
| 197 | + " assert (await test_nb(nbp, showerr=False))[0]\n", |
| 198 | + " assert not (await test_nb(nbp, showerr=False, profile=False))[0]" |
180 | 199 | ] |
181 | 200 | }, |
182 | 201 | { |
|
240 | 259 | " else: kw = {'method':'spawn'} if sys.platform=='darwin' else {}\n", |
241 | 260 | " wd_pth = cfg.nbs_path\n", |
242 | 261 | " with working_directory(wd_pth if (wd_pth and wd_pth.exists()) else os.getcwd()):\n", |
243 | | - " results = parallel(test_nb, files, skip_flags=skip_flags, force_flags=force_flags, n_workers=n_workers,\n", |
| 262 | + " results = parallel(_test_nb_sync, files, skip_flags=skip_flags, force_flags=force_flags, n_workers=n_workers,\n", |
244 | 263 | " basepath=cfg.config_path, pause=pause, do_print=do_print, verbose=verbose, save=save, **kw)\n", |
245 | 264 | " passed,times = zip(*results)\n", |
246 | 265 | " if all(passed): print(\"Success.\")\n", |
|
0 commit comments