diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d4c99b4..fed6924 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -38,7 +38,7 @@ jobs: uv pip install -e ".[test-browser]" - name: Get Playwright version id: pw-version - run: echo "version=$(uv run python -c 'import playwright; print(playwright.__version__)')" >> "$GITHUB_OUTPUT" + run: echo "version=$(uv run python -c 'from importlib.metadata import version; print(version("playwright"))')" >> "$GITHUB_OUTPUT" - name: Cache Playwright browsers id: pw-cache uses: actions/cache@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index bf1405d..51cd1ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## [0.4.1] - 2026-05-01 + +### Changed + +- `Matrix`, `ModuleTreeWidget`, and `ChartSelect` now render a small "graduated to marimo core" hint in the cell when instantiated inside a marimo notebook, with a link to the equivalent marimo built-in (`marimo.ui.matrix`, marimo's built-in PyTorch formatter, and `marimo.ui.matplotlib` respectively). The widgets continue to work as before in Jupyter and other anywidget hosts. + ## 0.4.0 ### Fixed diff --git a/Makefile b/Makefile index c3a72bb..942d13f 100644 --- a/Makefile +++ b/Makefile @@ -74,10 +74,10 @@ clean: rm -rf .ipynb_checkpoints build dist drawdata.egg-info docs: - mkdocs build -f mkdocs.yml 2>&1 | grep -v '^\[WARNING\] Div at' + DISABLE_MKDOCS_2_WARNING=true uv run mkdocs build -f mkdocs.yml 2>&1 | grep -v '^\[WARNING\] Div at' uv run python scripts/copy_docs_md.py -docs-serve: +docs-serve: docs uv run python -m http.server --directory site docs-build: diff --git a/demos/chartselect.py b/demos/chartselect.py index 93558ca..4aa69bf 100644 --- a/demos/chartselect.py +++ b/demos/chartselect.py @@ -10,7 +10,7 @@ import marimo -__generated_with = "0.19.11" +__generated_with = "0.23.4" app = marimo.App() @@ -21,7 +21,7 @@ def _(): import numpy as np from wigglystuff import ChartSelect - return ChartSelect, mo, np, plt + return ChartSelect, mo, np @app.cell(hide_code=True) diff --git a/demos/matrix.py b/demos/matrix.py index c2f5e5a..43b2e6a 100644 --- a/demos/matrix.py +++ b/demos/matrix.py @@ -8,9 +8,10 @@ # "wigglystuff==0.3.1", # ] # /// + import marimo -__generated_with = "0.18.2" +__generated_with = "0.23.4" app = marimo.App(width="full") @@ -22,6 +23,7 @@ def _(): import altair as alt from wigglystuff import Matrix + return Matrix, alt, mo, np, pd diff --git a/pyproject.toml b/pyproject.toml index bee4395..b44620e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "wigglystuff" -version = "0.4.0" +version = "0.4.1" description = "Collection of Anywidget Widgets" readme = "README.md" requires-python = ">=3.10" diff --git a/uv.lock b/uv.lock index 9463876..66d6038 100644 --- a/uv.lock +++ b/uv.lock @@ -4050,7 +4050,7 @@ wheels = [ [[package]] name = "wigglystuff" -version = "0.4.0" +version = "0.4.1" source = { editable = "." } dependencies = [ { name = "anywidget" }, diff --git a/wigglystuff/_marimo_notice.py b/wigglystuff/_marimo_notice.py new file mode 100644 index 0000000..dc2e186 --- /dev/null +++ b/wigglystuff/_marimo_notice.py @@ -0,0 +1,36 @@ +"""Internal helper for pointing marimo users at built-in equivalents.""" + +from __future__ import annotations + + +_STYLE = ( + "font-size: 0.875em; " + "padding: 8px 12px; margin: 8px 0; " + "border-left: 3px solid #f59e0b; " + "background: rgba(245, 158, 11, 0.10); " + "border-radius: 0 4px 4px 0;" +) + + +def warn_if_in_marimo(widget_name: str, message_html: str) -> None: + """Render a small graduation hint in the cell when running inside marimo. + + No-op in plain Jupyter or non-notebook contexts so users without a + marimo built-in alternative are not bothered. + + ``message_html`` is treated as raw HTML so call sites can embed + ```` links and ```` tags directly. + """ + try: + import marimo as mo + except ImportError: + return + if not mo.running_in_notebook(): + return + html = ( + f'
' + f"wigglystuff.{widget_name}" + f" has graduated to marimo core. {message_html}" + f"
" + ) + mo.output.append(mo.Html(html)) diff --git a/wigglystuff/chart_select.py b/wigglystuff/chart_select.py index 7e75dfb..eba553a 100644 --- a/wigglystuff/chart_select.py +++ b/wigglystuff/chart_select.py @@ -12,6 +12,7 @@ from anywidget import AnyWidget import traitlets +from ._marimo_notice import warn_if_in_marimo from .chart_puck import extract_axes_info, fig_to_base64 @@ -21,6 +22,12 @@ class ChartSelect(AnyWidget): Allows interactive box or lasso (freehand) selection on a static matplotlib chart. Returns selection coordinates in data space for user-side filtering. + Note: + This widget has graduated to marimo core. If you are using marimo, + prefer [`marimo.ui.matplotlib`](https://docs.marimo.io/guides/working_with_data/plotting/#matplotlib). + `ChartSelect` will continue to work in plain Jupyter and other + anywidget hosts. + Examples: Basic usage: @@ -117,6 +124,12 @@ def __init__( selection_opacity: Opacity of selection fill (0-1). **kwargs: Forwarded to ``AnyWidget``. """ + warn_if_in_marimo( + "ChartSelect", + 'Use
' + "marimo.ui.matplotlib instead.", + ) x_bounds, y_bounds, axes_pixel_bounds, width_px, height_px, x_scale, y_scale = extract_axes_info( fig ) diff --git a/wigglystuff/matrix.py b/wigglystuff/matrix.py index ea9d4f6..8c5b090 100644 --- a/wigglystuff/matrix.py +++ b/wigglystuff/matrix.py @@ -5,10 +5,18 @@ import numpy as np import traitlets +from ._marimo_notice import warn_if_in_marimo + class Matrix(anywidget.AnyWidget): """Spreadsheet-like numeric editor with bounds, naming, and symmetry helpers. + Note: + This widget has graduated to marimo core. If you are using marimo, + prefer [`marimo.ui.matrix`](https://docs.marimo.io/api/inputs/matrix/). + `Matrix` will continue to work in plain Jupyter and other anywidget + hosts. + Examples: ```python from wigglystuff import Matrix @@ -68,6 +76,12 @@ def __init__( mirror: If ``True``, mirror edits symmetrically across the diagonal. **kwargs: Forwarded to ``anywidget.AnyWidget``. """ + warn_if_in_marimo( + "Matrix", + 'Use ' + "marimo.ui.matrix instead.", + ) if matrix is not None: matrix_array = np.array(matrix) if matrix_array.min() < min_value: diff --git a/wigglystuff/module_tree.py b/wigglystuff/module_tree.py index 9670a3b..f9f7bd3 100644 --- a/wigglystuff/module_tree.py +++ b/wigglystuff/module_tree.py @@ -6,6 +6,8 @@ import anywidget import traitlets +from ._marimo_notice import warn_if_in_marimo + def _is_uninitialized(param): """Check if a parameter is a lazy/uninitialized parameter.""" @@ -137,6 +139,12 @@ class ModuleTreeWidget(anywidget.AnyWidget): Displays the full module hierarchy with parameter counts, shapes, trainable/frozen/buffer badges, and a density indicator. + Note: + This widget has graduated to marimo core. If you are using marimo, + you can simply return an ``nn.Module`` from a cell — marimo's + built-in PyTorch formatter will render it. ``ModuleTreeWidget`` + will continue to work in plain Jupyter and other anywidget hosts. + Examples: ```python import torch.nn as nn @@ -169,6 +177,11 @@ def __init__( module: A PyTorch ``nn.Module`` to visualise. initial_expand_depth: Number of tree levels to expand initially. """ + warn_if_in_marimo( + "ModuleTreeWidget", + "marimo's built-in PyTorch formatter will render an " + "nn.Module returned from a cell.", + ) super().__init__(initial_expand_depth=initial_expand_depth) if module is not None: self.tree = _extract_tree(module)