testbook
testbook copied to clipboard
Is it possible to call a function recieved as a reference with a parameter of type DataFrame
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