diff --git a/nbdev/test.py b/nbdev/test.py index d819e69a8..4a04e2ed3 100644 --- a/nbdev/test.py +++ b/nbdev/test.py @@ -20,6 +20,7 @@ from .doclinks import * from .process import NBProcessor, nb_lang from .frontmatter import nb_frontmatter +from .processors import _default_exp from fastcore.nbio import * from execnb.shell import * @@ -58,6 +59,8 @@ def _no_eval(cell): start = time.time() if profile is None: profile = bool(get_config(fn.parent).exec_profile) k = CaptureShell(fn, profile=profile) + exp = _default_exp(nb) + if exp and is_nbdev(fn.parent): k.user_ns['__file__'] = str(get_config(fn.parent).lib_path/(exp.replace('.','/') + '.py')) if do_print: print(f'Starting {fn}') try: with working_directory(fn.parent): @@ -73,7 +76,6 @@ def _no_eval(cell): if prev_test is None: os.environ.pop('IN_TEST', None) else: os.environ['IN_TEST'] = prev_test - # %% ../nbs/api/12_test.ipynb #d8bf1f1b-935d-4b69-ba96-827c5d7213f0 def _keep_file( p:Path, # filename for which to check for `indicator_fname` diff --git a/nbs/api/12_test.ipynb b/nbs/api/12_test.ipynb index f1b025906..5147e397d 100644 --- a/nbs/api/12_test.ipynb +++ b/nbs/api/12_test.ipynb @@ -40,6 +40,7 @@ "from nbdev.doclinks import *\n", "from nbdev.process import NBProcessor, nb_lang\n", "from nbdev.frontmatter import nb_frontmatter\n", + "from nbdev.processors import _default_exp\n", "\n", "from fastcore.nbio import *\n", "from execnb.shell import *" @@ -86,6 +87,8 @@ " start = time.time()\n", " if profile is None: profile = bool(get_config(fn.parent).exec_profile)\n", " k = CaptureShell(fn, profile=profile)\n", + " exp = _default_exp(nb)\n", + " if exp and is_nbdev(fn.parent): k.user_ns['__file__'] = str(get_config(fn.parent).lib_path/(exp.replace('.','/') + '.py'))\n", " if do_print: print(f'Starting {fn}')\n", " try:\n", " with working_directory(fn.parent):\n", @@ -99,7 +102,7 @@ " return res,time.time()-start\n", " finally:\n", " if prev_test is None: os.environ.pop('IN_TEST', None)\n", - " else: os.environ['IN_TEST'] = prev_test\n" + " else: os.environ['IN_TEST'] = prev_test" ] }, { @@ -142,6 +145,26 @@ "assert not success" ] }, + { + "cell_type": "markdown", + "id": "239fbed8", + "metadata": {}, + "source": [ + "If a notebook declares a `default_exp`, `__file__` is set to the path of the module it exports to, so path-dependent code (e.g. `Path(__file__).parent`) behaves the same under test as in the exported module. An explicit `__file__ =` in a cell overrides this:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f07e8a6e", + "metadata": {}, + "outputs": [], + "source": [ + "_nb = Path('../../tests/file_var.ipynb')\n", + "success,duration = test_nb(_nb)\n", + "assert success" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/tests/file_var.ipynb b/tests/file_var.ipynb new file mode 100644 index 000000000..190d1c7ae --- /dev/null +++ b/tests/file_var.ipynb @@ -0,0 +1,50 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test `__file__` is set for exported notebooks" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| default_exp file_var" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "p = Path(__file__)\n", + "assert p.name == 'file_var.py' and p.parent.name == 'nbdev'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "__file__ = 'overridden'\n", + "assert __file__ == 'overridden'" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}