Skip to main content

testcell

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.

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.

pip install testcell

Quick Start

First import testcell:

import testcell

Then use it:

%%testcell
temp_var = "This won't pollute namespace"
temp_var
"This won't pollute namespace"
# 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:

%%testcell verbose
result = "isolated execution"
result
### 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:

%%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.

%%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:

%%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

my_global = "I'm in the global scope"
%%testcell
'my_global' in globals()
    True # my_global is available
%%testcelln
'my_global' in globals()
    False # my_global is NOT available
%%testcelln
globals().keys()
    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.

data = [1, 2, 3, 4, 5]
%%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.

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:

%%testcell verbose
result = "complex parsing"
(result,
 True)
# comment on last line
### 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)

Todo:

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

Metadata

Release files for testcell 0.0.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for testcell 0.0.8
File Size Uploaded Provenance
testcell-0.0.8.tar.gz 17.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for testcell 0.0.8
File Interpreter ABI Platform
testcell-0.0.8-py3-none-any.whl Python 3 none any Details

Total release size: 31.1 kB

Release files / testcell-0.0.8.tar.gz

Download URL testcell-0.0.8.tar.gz
Size 17.1 kB
Tags Source
SHA-256 checksum
How to use checksums
af0351a9d5759588484bd31ad4d5a5d48e4930653d0684f708b483f215fa0c82
BLAKE2b-256 checksum
How to use checksums
213d354194c468752082e6b73efc2655a3583c5bb22095388160256ff072332c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.11

Release files / testcell-0.0.8-py3-none-any.whl

Download URL testcell-0.0.8-py3-none-any.whl
Size 14.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b5685f37fff0ef17341147ad0a9b3a05407ad19bec6d6b400157da5a8b6701df
BLAKE2b-256 checksum
How to use checksums
31c7a245f7bf0d7f2f3aecaa53943fa302515444136dc5a08e19af5dd419e953
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.11

Security for testcell 0.0.8

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page