The functions that grab the cells containing tests (filtering with potential flags) and execute them

Until can build an actual package with chisel-nbdev python code, import my 00_export_scala.ipynb -> nbdev/export.py using this hacky method:

Everything that is not an exported cell is considered a test, so you should make sure your notebooks can all run smoothly (and fast) if you want to use this functionality as the CLI. You can mark some cells with special flags (like slow) to make sure they are only executed when you authorize it. Those flags should be configured in your settings.ini (separated by a | if you have several of them). You can also apply flags to one entire notebook by using the all option, e.g. #all_slow, in code cells.

If tst_flags=slow|fastai in settings.ini, you can:

  • mark slow tests with #slow flag
  • mark tests that depend on fastai with the #fastai flag.

Detect flags

The following functions detect the cells that should be excluded from the tests (unless their special flag is passed).

get_all_flags[source]

get_all_flags(cells)

Check for all test flags in cells

nb = read_nb("04_test_scala.ipynb")
assert get_all_flags(nb['cells']) == set()

get_cell_flags[source]

get_cell_flags(cell)

Check for any special test flag in cell

test_eq(get_cell_flags({'cell_type': 'code', 'source': "//hide\n"}), [])

Testing a notebook

class NoExportPreprocessor[source]

NoExportPreprocessor(*args, **kwargs) :: ExecutePreprocessor

An ExecutePreprocessor that executes cells that don't have a flag in flags

If there is a mix of different notebook kernels (i.e Scala and Python notebooks), we only want to run the Scala tests.

test_nb[source]

test_nb(fn, flags=None)

Execute tests in notebook in fn with flags

nbdev_test_nbs[source]

nbdev_test_nbs(fname:"A notebook name or glob to convert"=None, flags:"Space separated list of flags"=None, n_workers:"Number of workers to use"=None, verbose:"Print errors along the way"=True, timing:"Timing each notebook to see the ones are slow"=False, pause:"Pause time (in secs) between notebooks to avoid race conditions"=0.5)

Test in parallel the notebooks matching fname, passing along flags

# files

nbdev_read_nbs[source]

nbdev_read_nbs(fname:"A notebook name or glob to convert"=None)

Check all notebooks matching fname can be opened

nbdev_test_nbs()
[Path('/Users/jasonvranek/code/notebooks/chisel_nbdev/nbs/ToImport.ipynb'), Path('/Users/jasonvranek/code/notebooks/chisel_nbdev/nbs/import_chisel_mod.ipynb'), Path('/Users/jasonvranek/code/notebooks/chisel_nbdev/nbs/import_composed_mod.ipynb'), Path('/Users/jasonvranek/code/notebooks/chisel_nbdev/nbs/index.ipynb'), Path('/Users/jasonvranek/code/notebooks/chisel_nbdev/nbs/test.ipynb')]
testing /Users/jasonvranek/code/notebooks/chisel_nbdev/nbs/ToImport.ipynb
testing /Users/jasonvranek/code/notebooks/chisel_nbdev/nbs/import_chisel_mod.ipynb
Error in /Users/jasonvranek/code/notebooks/chisel_nbdev/nbs/import_chisel_mod.ipynb:
An error occurred while executing the following cell:
------------------
//export
import $file.^.nbdev.ModA, ModA._
------------------

Cannot resolve $file import: /Users/jasonvranek/code/notebooks/chisel_nbdev/nbdev/ModA.sc
: 

testing /Users/jasonvranek/code/notebooks/chisel_nbdev/nbs/import_composed_mod.ipynb
Error in /Users/jasonvranek/code/notebooks/chisel_nbdev/nbs/import_composed_mod.ipynb:
An error occurred while executing the following cell:
------------------
//export
import $file.^.nbdev.ModB, ModB._
------------------

Cannot resolve $file import: /Users/jasonvranek/code/notebooks/chisel_nbdev/nbdev/ModB.sc
: 

testing /Users/jasonvranek/code/notebooks/chisel_nbdev/nbs/index.ipynb
testing /Users/jasonvranek/code/notebooks/chisel_nbdev/nbs/test.ipynb
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-19-b1c77381ffda> in <module>
      1 # nbdev_test_nbs("test.ipynb")
----> 2 nbdev_test_nbs()

<ipython-input-16-3e7a1b620eb4> in nbdev_test_nbs(fname, flags, n_workers, verbose, timing, pause)
     18     os.chdir(Config().path("nbs_path"))
     19 #     results = parallel(_test_one, files, flags=flags, verbose=verbose, n_workers=n_workers, pause=pause)
---> 20     results = [_test_one(f, flags=flags, verbose=verbose) for f in files]#todo fix parallel tester
     21     passed,times = [r[0] for r in results],[r[1] for r in results]
     22     if all(passed): print("All tests are passing!")

<ipython-input-16-3e7a1b620eb4> in <listcomp>(.0)
     18     os.chdir(Config().path("nbs_path"))
     19 #     results = parallel(_test_one, files, flags=flags, verbose=verbose, n_workers=n_workers, pause=pause)
---> 20     results = [_test_one(f, flags=flags, verbose=verbose) for f in files]#todo fix parallel tester
     21     passed,times = [r[0] for r in results],[r[1] for r in results]
     22     if all(passed): print("All tests are passing!")

<ipython-input-15-f3b99b2c5eef> in _test_one(fname, flags, verbose)
      4     start = time.time()
      5     try:
----> 6         test_nb(fname, flags=flags)
      7         return True,time.time()-start
      8     except Exception as e:

<ipython-input-14-28122f25158c> in test_nb(fn, flags)
     10         ep = NoExportPreprocessor(flags, timeout=600, kernel_name='scala')
     11         pnb = nbformat.from_dict(nb)
---> 12         ep.preprocess(pnb)
     13     finally: os.environ.pop("IN_TEST")

~/Code/classes/jlab_3.8/lib/python3.8/site-packages/nbconvert/preprocessors/execute.py in preprocess(self, nb, resources, km)
    403         with self.setup_preprocessor(nb, resources, km=km):
    404             self.log.info("Executing notebook with kernel: %s" % self.kernel_name)
--> 405             nb, resources = super(ExecutePreprocessor, self).preprocess(nb, resources)
    406             info_msg = self._wait_for_reply(self.kc.kernel_info())
    407             nb.metadata['language_info'] = info_msg['content']['language_info']

~/Code/classes/jlab_3.8/lib/python3.8/site-packages/nbconvert/preprocessors/base.py in preprocess(self, nb, resources)
     67         """
     68         for index, cell in enumerate(nb.cells):
---> 69             nb.cells[index], resources = self.preprocess_cell(cell, resources, index)
     70         return nb, resources
     71 

<ipython-input-13-306abf9ec327> in preprocess_cell(self, cell, resources, index)
     11             if f not in self.flags: return cell, resources
     12         if check_re(cell, _re_notebook2script): return cell, resources
---> 13         return super().preprocess_cell(cell, resources, index)

~/Code/classes/jlab_3.8/lib/python3.8/site-packages/nbconvert/preprocessors/execute.py in preprocess_cell(self, cell, resources, cell_index, store_history)
    436             return cell, resources
    437 
--> 438         reply, outputs = self.run_cell(cell, cell_index, store_history)
    439         # Backwards compatibility for processes that wrap run_cell
    440         cell.outputs = outputs

~/Code/classes/jlab_3.8/lib/python3.8/site-packages/nbconvert/preprocessors/execute.py in run_cell(self, cell, cell_index, store_history)
    587                         # polling for output.
    588                         timeout = self._timeout_with_deadline(timeout, deadline)
--> 589                     msg = self.kc.iopub_channel.get_msg(timeout=timeout)
    590                 except Empty:
    591                     if polling_exec_reply:

~/Code/classes/jlab_3.8/lib/python3.8/site-packages/jupyter_client/blocking/channels.py in get_msg(self, block, timeout)
     45             if timeout is not None:
     46                 timeout *= 1000  # seconds to ms
---> 47             ready = self.socket.poll(timeout)
     48         else:
     49             ready = self.socket.poll(timeout=0)

~/Code/classes/jlab_3.8/lib/python3.8/site-packages/zmq/sugar/socket.py in poll(self, timeout, flags)
    791         p = self._poller_class()
    792         p.register(self, flags)
--> 793         evts = dict(p.poll(timeout))
    794         # return 0 if no events, otherwise return event bitfield
    795         return evts.get(self, 0)

~/Code/classes/jlab_3.8/lib/python3.8/site-packages/zmq/sugar/poll.py in poll(self, timeout)
    101         elif isinstance(timeout, float):
    102             timeout = int(timeout)
--> 103         return zmq_poll(self.sockets, timeout=timeout)
    104 
    105 

zmq/backend/cython/_poll.pyx in zmq.backend.cython._poll.zmq_poll()

~/Code/classes/jlab_3.8/lib/python3.8/site-packages/zmq/backend/cython/checkrc.pxd in zmq.backend.cython.checkrc._check_rc()

KeyboardInterrupt: