testbook icon indicating copy to clipboard operation
testbook copied to clipboard

Is it possible to call a function recieved as a reference with a parameter of type DataFrame

Open alonme opened this issue 4 years ago • 0 comments

I would like to test a function that recieves a DataFrame as input.

when trying to do that - it seems that the dataframe is converted to string and then the test crashes.

is this possible to do in another way?

Attaching stacktrace

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

    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.7/site-packages/testbook/client.py:131: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (<testbook.client.TestbookNotebookClient object at 0x111a4fd10>, {'id': '0eb76ee5', 'cell_type': 'code', 'metadata': {...                 ^\x1b[0m\n\x1b[0;31mSyntaxError\x1b[0m\x1b[0;31m:\x1b[0m EOL while scanning string literal\n']}]}, 28)
kwargs = {}

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

../.venv/lib/python3.7/site-packages/nbclient/util.py:74: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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

    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.7/site-packages/nbclient/util.py:53: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_UnixSelectorEventLoop running=False closed=False debug=False>
future = <Task finished coro=<NotebookClient.async_execute_cell() done, defined at /Users/alonmenczer/dev/analyses/.venv/lib/py...scanning string literal\n\nSyntaxError: EOL while scanning string literal (<ipython-input-5-b7ca873e05c5>, line 1)\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_runnung()
    
        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()

../../../.pyenv/versions/3.7.9/lib/python3.7/asyncio/base_events.py:587: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <testbook.client.TestbookNotebookClient object at 0x111a4fd10>
cell = {'id': '0eb76ee5', 'cell_type': 'code', 'metadata': {'execution': {'iopub.status.busy': '2021-05-19T14:26:00.834130Z',...                      ^\x1b[0m\n\x1b[0;31mSyntaxError\x1b[0m\x1b[0;31m:\x1b[0m EOL while scanning string literal\n']}]}
cell_index = 28, 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.7/site-packages/nbclient/client.py:857: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <testbook.client.TestbookNotebookClient object at 0x111a4fd10>
cell = {'id': '0eb76ee5', 'cell_type': 'code', 'metadata': {'execution': {'iopub.status.busy': '2021-05-19T14:26:00.834130Z',...                      ^\x1b[0m\n\x1b[0;31mSyntaxError\x1b[0m\x1b[0;31m:\x1b[0m EOL while scanning string literal\n']}]}
exec_reply = {'buffers': [], 'content': {'ename': 'SyntaxError', 'engine_info': {'engine_id': -1, 'engine_uuid': '9f48ce88-718d-4cd...e, 'engine': '9f48ce88-718d-4cd4-9d87-6c93dcd2a62c', 'started': '2021-05-19T14:26:00.832539Z', '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                       bar(*("Empty DataFrame
E           Columns: []
E           Index: []", ), **{})
E           
E           ------------------
E           
E             File "<ipython-input-5-b7ca873e05c5>", line 1
E               bar(*("Empty DataFrame
E                                     ^
E           SyntaxError: EOL while scanning string literal
E           
E           SyntaxError: EOL while scanning string literal (<ipython-input-5-b7ca873e05c5>, line 1)

../.venv/lib/python3.7/site-packages/nbclient/client.py:760: CellExecutionError

During handling of the above exception, another exception occurred:

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

    @testbook("./analysis.ipynb", execute=["imports", "helper_functions"])
    def test_dataframe(tb):
        bar = tb.ref("bar")
>       bar(pd.DataFrame())

test_engagement_buckets.py:45: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../.venv/lib/python3.7/site-packages/testbook/reference.py:85: in __call__
    return self.tb.value(code)
../.venv/lib/python3.7/site-packages/testbook/client.py:271: in value
    result = self.inject(code, pop=True)
../.venv/lib/python3.7/site-packages/testbook/client.py:235: in inject
    cell = TestbookNode(self.execute_cell(inject_idx)) if run else TestbookNode(code_cell)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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

    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                           bar(*("Empty DataFrame
E               Columns: []
E               Index: []", ), **{})
E               
E               ------------------
E               
E                 File "<ipython-input-5-b7ca873e05c5>", line 1
E                   bar(*("Empty DataFrame
E                                         ^
E               SyntaxError: EOL while scanning string literal
E               
E               SyntaxError: EOL while scanning string literal (<ipython-input-5-b7ca873e05c5>, line 1)

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

alonme avatar May 19 '21 14:05 alonme