nteract / testbook

🧪 📗 Unit test your Jupyter Notebooks the right way
https://testbook.readthedocs.io
BSD 3-Clause "New" or "Revised" License
418 stars 37 forks source link

testbook loads wrong signature for function #137

Open midumitrescu opened 2 years ago

midumitrescu commented 2 years ago

Hello,

i have following test:

import testbook
import numpy as np
from assertpy import assert_that
from pytest import fixture

@fixture(scope='module')
def tb():
    with testbook.testbook('h2_2.ipynb', execute=True) as tb:
        yield tb

def test_some_small_function(tb):
    some_function = tb.ref("some_function")
    test_w_1_0 = np.array([1])
    test_no_bias = np.array([0])
    test_w_2_1 = np.array([1])
    print(locals())
    assert_that(some_function(0, test_w_1_0, test_no_bias, test_w_2_1, np.sign)).contains([0, 1, -1])

having in the notebook:

def some_function(input_var: float, first: np.ndarray, bias: np.ndarray, second: np.ndarray, the_transfer_function):
    h: np.ndarray = input_var * first - bias
    return np.dot(second, the_transfer_function(h))

and I get the following TypeError error:

E TypeError Traceback (most recent call last) E /var/folders/jk/bq46f4ys107bjb6jwvn0yhqr0000gp/T/ipykernel_52132/3127954361.py in E ----> 1 some_function(*(0, "[1]", "[0]", "[1]", "<ufunc 'sign'>", ), *{}) E
E /var/folders/jk/bq46f4ys107bjb6jwvn0yhqr0000gp/T/ipykernel_52132/179938020.py in some_function(input_var, first, bias, second, the_transfer_function) E 1 def some_function(input_var: float, first: np.ndarray, bias: np.ndarray, second: np.ndarray, the_transfer_function): E ----> 2 h: np.ndarray = input_var
first - bias E 3 return np.dot(second, the_transfer_function(h)) E
E TypeError: unsupported operand type(s) for -: 'str' and 'str' E TypeError: unsupported operand type(s) for -: 'str' and 'str'

I have added extra type information to make it clear to you the intend of the code.

Tests inside the notebook are running successfully

test_h2.py::test_some_small_function /Users/1000ber-5078/PycharmProjects/machine-intelligence/venv/lib/python3.8/site-packages/debugpy/_vendored/force_pydevd.py:20: UserWarning: incompatible copy of pydevd already imported: /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/init.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/_pydev_calltip_util.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/_pydev_completer.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/_pydev_filesystem_encoding.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/_pydev_imports_tipper.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/_pydev_tipper_common.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/fix_getpass.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_code_executor.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_console_types.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_imports.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_ipython_code_executor.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_ipython_console_011.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_is_thread_alive.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_log.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_monkey.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_override.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_stdin.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_imps/init.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_imps/_pydev_execfile.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_imps/_pydev_saved_modules.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/init.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_additional_thread_info.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_additional_thread_info_regular.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_breakpointhook.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_breakpoints.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_bytecode_utils.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_collect_try_except_info.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_comm_constants.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_command_line_handling.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_console.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_console_integration.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_console_pytest.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_custom_frames.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_cython_darwin_38_64.cpython-38-darwin.so /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_cython_darwin_38_64.cpython-38-darwin.so /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_cython_wrapper.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_dont_trace.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_dont_trace_files.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_exec2.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_extension_api.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_extension_utils.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_frame.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_frame_utils.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_import_class.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_io.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_kill_all_pydevd_threads.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_plugin_utils.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_process_net_command.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_resolver.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_save_locals.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_signature.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_tables.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_trace_api.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_trace_dispatch.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_traceproperty.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_utils.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_vars.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_vm_type.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_xml.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_frame_eval/init.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_frame_eval/pydevd_frame_eval_main.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydev_ipython/init.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydev_ipython/inputhook.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydev_ipython/matplotlibtools.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_concurrency_analyser/init.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_concurrency_analyser/pydevd_concurrency_logger.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_concurrency_analyser/pydevd_thread_wrappers.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_file_utils.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_plugins/init.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_plugins/django_debug.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_plugins/extensions/init.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_plugins/extensions/types/init.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_plugins/extensions/types/pydevd_helpers.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_plugins/extensions/types/pydevd_plugin_numpy_types.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_plugins/extensions/types/pydevd_plugins_django_form_str.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_plugins/jinja2_debug.py /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd_tracing.py warnings.warn(msg + ':\n {}'.format('\n '.join(_unvendored))) [IPKernelApp] WARNING | debugpy_stream undefined, debugging will not be enabled FAILED [100%]{'tb': <testbook.client.TestbookNotebookClient object at 0x7f9ef824d2e0>, 'some_function': '<function some_function at 0x7fb2b2e70c10>', 'test_w_1_0': array([1]), 'test_no_bias': array([0]), 'test_w_2_1': array([1])}

test_h2.py:12 (test_some_small_function) self = <testbook.client.TestbookNotebookClient object at 0x7f9ef824d2e0> cell = [8], kwargs = {}, cell_indexes = [8], executed_cells = [], idx = 8

def execute_cell(self, cell, **kwargs) -> Union[Dict, List[Dict]]:
    """
    Executes a cell or list of cells
    """
    if isinstance(cell, slice):
        start, stop = self._cell_index(cell.start), self._cell_index(cell.stop)
        if cell.step is not None:
            raise TestbookError('testbook does not support step argument')

        cell = range(start, stop + 1)
    elif isinstance(cell, str) or isinstance(cell, int):
        cell = [cell]

    cell_indexes = cell

    if all(isinstance(x, str) for x in cell):
        cell_indexes = [self._cell_index(tag) for tag in cell]

    executed_cells = []
    for idx in cell_indexes:
        try:
          cell = super().execute_cell(self.nb['cells'][idx], idx, **kwargs)

../venv/lib/python3.8/site-packages/testbook/client.py:133:


args = (<testbook.client.TestbookNotebookClient object at 0x7f9ef824d2e0>, {'id': '6ac327d5', 'cell_type': 'code', 'metadata'...0m\x1b0;31mTypeError\x1b[0m: unsupported operand type(s) for -: 'str' and 'str'"]} for -: 'str' and 'str'"]}]}, 8) kwargs = {}

def wrapped(*args, **kwargs):
  return just_run(coro(*args, **kwargs))

../venv/lib/python3.8/site-packages/nbclient/util.py:78:


coro = <coroutine object NotebookClient.async_execute_cell at 0x7f9ef81fea40>

def just_run(coro: Awaitable) -> Any:
    """Make the coroutine run, even if there is an event loop running (using nest_asyncio)"""
    # original from vaex/asyncio.py
    loop = asyncio._get_running_loop()
    if loop is None:
        had_running_loop = False
        try:
            loop = asyncio.get_event_loop()
        except RuntimeError:
            # we can still get 'There is no current event loop in ...'
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
    else:
        had_running_loop = True
    if had_running_loop:
        # if there is a running loop, we patch using nest_asyncio
        # to have reentrant event loops
        check_ipython()
        import nest_asyncio
        nest_asyncio.apply()
        check_patch_tornado()
  return loop.run_until_complete(coro)

../venv/lib/python3.8/site-packages/nbclient/util.py:57:


self = <_UnixSelectorEventLoop running=False closed=False debug=False> future = <Task finished name='Task-48' coro=<NotebookClient.async_execute_cell() done, defined at /Users/1000ber-5078/PycharmPr...rted operand type(s) for -: \'str\' and \'str\'\nTypeError: unsupported operand type(s) for -: \'str\' and \'str\'\n')>

def run_until_complete(self, future):
    """Run until the Future is done.

    If the argument is a coroutine, it is wrapped in a Task.

    WARNING: It would be disastrous to call run_until_complete()
    with the same coroutine twice -- it would wrap it in two
    different Tasks and that can't be good.

    Return the Future's result, or raise its exception.
    """
    self._check_closed()
    self._check_running()

    new_task = not futures.isfuture(future)
    future = tasks.ensure_future(future, loop=self)
    if new_task:
        # An exception is raised if the future didn't complete, so there
        # is no need to log the "destroy pending task" message
        future._log_destroy_pending = False

    future.add_done_callback(_run_until_complete_cb)
    try:
        self.run_forever()
    except:
        if new_task and future.done() and not future.cancelled():
            # The coroutine raised a BaseException. Consume the exception
            # to not log a warning, the caller doesn't have access to the
            # local task.
            future.exception()
        raise
    finally:
        future.remove_done_callback(_run_until_complete_cb)
    if not future.done():
        raise RuntimeError('Event loop stopped before Future completed.')
  return future.result()

/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/base_events.py:616:


self = <testbook.client.TestbookNotebookClient object at 0x7f9ef824d2e0> cell = {'id': '6ac327d5', 'cell_type': 'code', 'metadata': {'execution': {'iopub.status.busy': '2021-10-23T15:57:12.875064Z',...x1b[0m\x1b0;31mTypeError\x1b[0m: unsupported operand type(s) for -: 'str' and 'str'"]} for -: 'str' and 'str'"]}]} cell_index = 8, execution_count = None, store_history = True

async def async_execute_cell(
        self,
        cell: NotebookNode,
        cell_index: int,
        execution_count: t.Optional[int] = None,
        store_history: bool = True) -> NotebookNode:
    """
    Executes a single code cell.

    To execute all cells see :meth:`execute`.

    Parameters
    ----------
    cell : nbformat.NotebookNode
        The cell which is currently being processed.
    cell_index : int
        The position of the cell within the notebook object.
    execution_count : int
        The execution count to be assigned to the cell (default: Use kernel response)
    store_history : bool
        Determines if history should be stored in the kernel (default: False).
        Specific to ipython kernels, which can store command histories.

    Returns
    -------
    output : dict
        The execution output payload (or None for no output).

    Raises
    ------
    CellExecutionError
        If execution failed and should raise an exception, this will be raised
        with defaults about the failure.

    Returns
    -------
    cell : NotebookNode
        The cell which was just processed.
    """
    assert self.kc is not None
    if cell.cell_type != 'code' or not cell.source.strip():
        self.log.debug("Skipping non-executing cell %s", cell_index)
        return cell

    if self.record_timing and 'execution' not in cell['metadata']:
        cell['metadata']['execution'] = {}

    self.log.debug("Executing cell:\n%s", cell.source)

    cell_allows_errors = (not self.force_raise_errors) and (
        self.allow_errors
        or "raises-exception" in cell.metadata.get("tags", []))

    parent_msg_id = await ensure_async(
        self.kc.execute(
            cell.source,
            store_history=store_history,
            stop_on_error=not cell_allows_errors
        )
    )
    # We launched a code cell to execute
    self.code_cells_executed += 1
    exec_timeout = self._get_timeout(cell)

    cell.outputs = []
    self.clear_before_next_output = False

    task_poll_kernel_alive = asyncio.ensure_future(
        self._async_poll_kernel_alive()
    )
    task_poll_output_msg = asyncio.ensure_future(
        self._async_poll_output_msg(parent_msg_id, cell, cell_index)
    )
    self.task_poll_for_reply = asyncio.ensure_future(
        self._async_poll_for_reply(
            parent_msg_id, cell, exec_timeout, task_poll_output_msg, task_poll_kernel_alive
        )
    )
    try:
        exec_reply = await self.task_poll_for_reply
    except asyncio.CancelledError:
        # can only be cancelled by task_poll_kernel_alive when the kernel is dead
        task_poll_output_msg.cancel()
        raise DeadKernelError("Kernel died")
    except Exception as e:
        # Best effort to cancel request if it hasn't been resolved
        try:
            # Check if the task_poll_output is doing the raising for us
            if not isinstance(e, CellControlSignal):
                task_poll_output_msg.cancel()
        finally:
            raise

    if execution_count:
        cell['execution_count'] = execution_count
  self._check_raise_for_error(cell, exec_reply)

../venv/lib/python3.8/site-packages/nbclient/client.py:862:


self = <testbook.client.TestbookNotebookClient object at 0x7f9ef824d2e0> cell = {'id': '6ac327d5', 'cell_type': 'code', 'metadata': {'execution': {'iopub.status.busy': '2021-10-23T15:57:12.875064Z',...x1b[0m\x1b0;31mTypeError\x1b[0m: unsupported operand type(s) for -: 'str' and 'str'"]} for -: 'str' and 'str'"]}]} exec_reply = {'buffers': [], 'content': {'ename': 'TypeError', 'engine_info': {'engine_id': -1, 'engine_uuid': '7b8e70ee-5b55-4029-...e, 'engine': '7b8e70ee-5b55-4029-888b-a23a76f683ca', 'started': '2021-10-23T15:57:12.869603Z', 'status': 'error'}, ...}

def _check_raise_for_error(
        self,
        cell: NotebookNode,
        exec_reply: t.Optional[t.Dict]) -> None:

    if exec_reply is None:
        return None

    exec_reply_content = exec_reply['content']
    if exec_reply_content['status'] != 'error':
        return None

    cell_allows_errors = (not self.force_raise_errors) and (
        self.allow_errors
        or exec_reply_content.get('ename') in self.allow_error_names
        or "raises-exception" in cell.metadata.get("tags", []))

    if not cell_allows_errors:
      raise CellExecutionError.from_cell_and_msg(cell, exec_reply_content)

E nbclient.exceptions.CellExecutionError: An error occurred while executing the following cell: E ------------------ E
E some_function(*(0, "[1]", "[0]", "[1]", "<ufunc 'sign'>", ), *{}) E
E ------------------ E
E --------------------------------------------------------------------------- E TypeError Traceback (most recent call last) E /var/folders/jk/bq46f4ys107bjb6jwvn0yhqr0000gp/T/ipykernel_52132/3127954361.py in E ----> 1 some_function(
(0, "[1]", "[0]", "[1]", "<ufunc 'sign'>", ), *{}) E
E /var/folders/jk/bq46f4ys107bjb6jwvn0yhqr0000gp/T/ipykernel_52132/179938020.py in some_function(input_var, first, bias, second, the_transfer_function) E 1 def some_function(input_var: float, first: np.ndarray, bias: np.ndarray, second: np.ndarray, the_transfer_function): E ----> 2 h: np.ndarray = input_var
first - bias E 3 return np.dot(second, the_transfer_function(h)) E
E TypeError: unsupported operand type(s) for -: 'str' and 'str' E TypeError: unsupported operand type(s) for -: 'str' and 'str'

../venv/lib/python3.8/site-packages/nbclient/client.py:765: CellExecutionError

During handling of the above exception, another exception occurred:

tb = <testbook.client.TestbookNotebookClient object at 0x7f9ef824d2e0>

def test_some_small_function(tb):
    some_function = tb.ref("some_function")
    test_w_1_0 = np.array([1])
    test_no_bias = np.array([0])
    test_w_2_1 = np.array([1])
    print(locals())
  assert_that(some_function(0, test_w_1_0, test_no_bias, test_w_2_1, np.sign)).contains([0, 1, -1])

test_h2.py:19:


../venv/lib/python3.8/site-packages/testbook/reference.py:85: in call return self.tb.value(code) ../venv/lib/python3.8/site-packages/testbook/client.py:273: in value result = self.inject(code, pop=True) ../venv/lib/python3.8/site-packages/testbook/client.py:237: in inject cell = TestbookNode(self.execute_cell(inject_idx)) if run else TestbookNode(code_cell)


self = <testbook.client.TestbookNotebookClient object at 0x7f9ef824d2e0> cell = [8], kwargs = {}, cell_indexes = [8], executed_cells = [], idx = 8

def execute_cell(self, cell, **kwargs) -> Union[Dict, List[Dict]]:
    """
    Executes a cell or list of cells
    """
    if isinstance(cell, slice):
        start, stop = self._cell_index(cell.start), self._cell_index(cell.stop)
        if cell.step is not None:
            raise TestbookError('testbook does not support step argument')

        cell = range(start, stop + 1)
    elif isinstance(cell, str) or isinstance(cell, int):
        cell = [cell]

    cell_indexes = cell

    if all(isinstance(x, str) for x in cell):
        cell_indexes = [self._cell_index(tag) for tag in cell]

    executed_cells = []
    for idx in cell_indexes:
        try:
            cell = super().execute_cell(self.nb['cells'][idx], idx, **kwargs)
        except CellExecutionError as ce:
          raise TestbookRuntimeError(ce.evalue, ce, self._get_error_class(ce.ename))

E testbook.exceptions.TestbookRuntimeError: An error occurred while executing the following cell: E ------------------ E
E some_function(*(0, "[1]", "[0]", "[1]", "<ufunc 'sign'>", ), *{}) E
E ------------------ E
E --------------------------------------------------------------------------- E TypeError Traceback (most recent call last) E /var/folders/jk/bq46f4ys107bjb6jwvn0yhqr0000gp/T/ipykernel_52132/3127954361.py in E ----> 1 some_function(
(0, "[1]", "[0]", "[1]", "<ufunc 'sign'>", ), *{}) E
E /var/folders/jk/bq46f4ys107bjb6jwvn0yhqr0000gp/T/ipykernel_52132/179938020.py in some_function(input_var, first, bias, second, the_transfer_function) E 1 def some_function(input_var: float, first: np.ndarray, bias: np.ndarray, second: np.ndarray, the_transfer_function): E ----> 2 h: np.ndarray = input_var
first - bias E 3 return np.dot(second, the_transfer_function(h)) E
E TypeError: unsupported operand type(s) for -: 'str' and 'str' E TypeError: unsupported operand type(s) for -: 'str' and 'str'

../venv/lib/python3.8/site-packages/testbook/client.py:135: TestbookRuntimeError

======================== 1 failed, 12 warnings in 2.97s ========================

Process finished with exit code 1

rohitsanj commented 2 years ago

Hey @midumitrescu! It looks like you're trying to pass in a bunch of non-JSON serializable types into the testbook reference function call - types like non-native numpy array implementations, and a function type.

If you'd like to call your function with such types, we have a way of injecting all your code into the notebook, by using tb.inject

So your test would look something like so:

def test_some_small_function(tb):
    tb.inject("""
       import numpy as np
       from assertpy import assert_that
       from pytest import fixture

       test_w_1_0 = np.array([1])
       test_no_bias = np.array([0])
       test_w_2_1 = np.array([1])
       print(locals())
       assert_that(some_function(0, test_w_1_0, test_no_bias, test_w_2_1, np.sign)).contains([0, 1, -1])
    """)

(FYI: You would not need to worry about indentation because we dedent the code string before injecting)

Let me know if that solves your issue. Thanks!