Metadata-Version: 2.4
Name: testcell
Version: 0.0.8
Summary: testcell prevents your testing cells from affecting the global namespace
Home-page: https://github.com/artste/testcell
Author: Stefano Giomo
Author-email: artste@users.noreply.github.com
License: Apache Software License 2.0
Keywords: nbdev jupyter notebook python
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: License :: OSI Approved :: Apache Software License
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: Pillow; extra == "dev"
Requires-Dist: matplotlib; extra == "dev"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-python
Dynamic: summary

# testcell


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

One good thing about working in Jupyter notebooks is that they make it
easy to quickly test a bit of code by evaluating it in notebook cell.
But one bad thing is that the *definitions* resulting from that
evaluation hang around afterwards, when all you wanted was just to test
that one bit of code.

`%%testcell` is a simple simple solution to that problem. It lets you
execute notebook cells in isolation. Test code, try snippets, and
experiment freely: no variables, functions, classes, or imports are left
behind. This helps to keep your namespace clean, so that leftover
symbols do not confuse later work.

**WARNING:** this doesn’t protect you from *the side effects of your
code* like deleting a file or mutating the state of a global variable.

[![](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/artste/testcell/blob/main/demo/testcell_demo.ipynb)
[![](https://kaggle.com/static/images/open-in-kaggle.svg)](https://www.kaggle.com/artste/introducing-testcell)
[![](https://modal-cdn.com/open-in-modal.svg)](https://modal.com/notebooks/new/https://github.com/artste/testcell/blob/main/demo/testcell_demo.ipynb)

## Install

Lightweight and reliable: `%%testcell` depends only on IPython and works
in all major notebook environments including Jupyter, Colab, Kaggle,
Modal, Solveit, and the IPython console.

``` sh
pip install testcell
```

## Quick Start

First import `testcell`:

``` python
import testcell
```

Then use it:

``` python
%%testcell
temp_var = "This won't pollute namespace"
temp_var
```

    "This won't pollute namespace"

``` python
# temp_var doesn't exist — it was only defined inside the test cell
temp_var  # NameError: name 'temp_var' is not defined
```

## How it works

Import `testcell` and use the `%%testcell` magic at the top of any cell.
Under the hood, your code is wrapped in a temporary function that
executes and then deletes itself.

Use `verbose` to see the generated wrapper code:

``` python
%%testcell verbose
result = "isolated execution"
result
```

``` python
### BEGIN
def _test_cell_():
    #| echo: false
    result = "isolated execution"
    return result # %%testcell
try:
    _ = _test_cell_()
finally:
    del _test_cell_
_ # This will be added to global scope
### END
```

    'isolated execution'

## Suppressing output

Like normal Jupyter cells, add a semicolon `;` to the last statement to
suppress display:

``` python
%%testcell
calculation = 42 * 2
calculation;
```

No output is displayed, and `calculation` still doesn’t leak to globals.

## Skip execution

Skip cells without deleting code using the `skip` command.

**IMPORTANT**: This is especially useful in notebook environments like
**Colab, Kaggle, and Modal** where you can’t use Jupyter’s “Raw cell”
type to disable execution.

``` python
%%testcell skip
raise ValueError('This will not execute')
```

    <testcell.MessageBox object>

To skip all `%%testcell` cells at once (useful for production runs),
use: `testcell.global_skip = True`

## Visual marking

Use `banner` to display a colored indicator at the top of cell output,
making test cells instantly recognizable:

``` python
%%testcell banner
"clearly marked"
```

    <testcell.MessageBox object>

    'clearly marked'

**The banner adapts to your environment.** In HTML-based notebooks like
Jupyter, it displays as a full-width colored box. In console
environments like IPython, it appears as text with an emoji.

Colors and emojis are fully customizable through `testcell.params`.

**IMPORTANT**: To enable banners for all `%%testcell` cells, use:
**`testcell.global_use_banner = True`**

## Run in complete isolation

`%%testcelln` is a shortcut for `%%testcell noglobals` and executes
cells with **zero access** to your notebook’s global scope. Only
Python’s `__builtins__` are available.

This is powerful for: - **Detecting hidden dependencies**: catch when
your code accidentally relies on global variables - **Testing
portability**: verify functions work standalone - **Clean slate
execution**: run code exactly as it would in a fresh Python session

``` python
my_global = "I'm in the global scope"
```

``` python
%%testcell
'my_global' in globals()
```

``` python
    True # my_global is available
```

``` python
%%testcelln
'my_global' in globals()
```

``` python
    False # my_global is NOT available
```

``` python
%%testcelln
globals().keys()
```

``` python
    dict_keys(['__builtins__'])
```

## Explicit dependencies

The `(inputs)->(outputs)` syntax gives you precise control: you can pass
any symbol (variables, functions, classes) into the isolated context and
save only chosen ones back to globals.

This **forces explicit dependency declaration**, giving you full control
over what enters and exits the cell. It prevents accidental reliance on
symbols from the main context that would hurt you when exporting the
code.

``` python
data = [1, 2, 3, 4, 5]
```

``` python
%%testcelln (data)->(calculate_stats)
# Only 'data' is available, only 'calculate_stats' is saved

def calculate_stats(values):
    return {
        'mean': sum(values) / len(values),
        'min': min(values),
        'max': max(values)
    }

# Test it works
print(calculate_stats(data))
```

    {'mean': 3.0, 'min': 1, 'max': 5}

`calculate_stats` now **exists in globals**. No test code or
intermediate variables leaked.

``` python
calculate_stats([10, 20, 30])
```

    {'mean': 20.0, 'min': 10, 'max': 30}

## Advanced parsing

Thanks to Python’s `ast` module, `%%testcell` correctly handles complex
code patterns including comments on the last line and multi-line
statements:

``` python
%%testcell verbose
result = "complex parsing"
(result,
 True)
# comment on last line
```

``` python
### BEGIN
def _test_cell_():
    #| echo: false
    result = "complex parsing"
    return (result,
     True) # %%testcell
try:
    _ = _test_cell_()
finally:
    del _test_cell_
_ # This will be added to global scope
### END
```

    ('complex parsing', True)

## Links:

- PROJECT PAGE: <https://github.com/artste/testcell>
- DOCUMENTATION: <https://artste.github.io/testcell>
- PYPI: <https://pypi.org/project/testcell>
- DETAILED DEMO:
  <https://github.com/artste/testcell/blob/main/demo/testcell_demo.ipynb>
- USE CASE ZOO:
  <https://github.com/artste/testcell/blob/main/demo/testcell_zoo.ipynb>
- LAUNCHING BLOG: [Introducing
  `%%testcell`](https://artste.github.io/blog/posts/introducing-testcell)
- COLAB DEMO:
  [testcell_demo.ipynb](https://colab.research.google.com/github/artste/testcell/blob/main/demo/testcell_demo.ipynb)
- KAGGLE SAMPLE NOTEBOOK:
  <https://www.kaggle.com/artste/introducing-testcell>

## Todo:

- Install as a plugin to enable it by default like other cell’s magic.
